def user(): url = __check_login('user') if url: return redirect(url) usererrors = [] userform = UserForm(prefix="user") user = get_user(session['email']) if request.method == 'GET': # Add default values userform.email.data = user.email userform.first_name.data = user.short_name userform.last_name.data = user.family_name userform.alias.data = user.alias elif userform.validate_on_submit(): if (validate_login(session['email'], userform.password.data)): # Update info user.email = userform.email.data user.short_name = userform.first_name.data user.family_name = userform.last_name.data user.full_name = userform.first_name.data + " " + userform.last_name.data user.alias = userform.alias.data if userform.alias.data != "" else None if (userform.new_password.data): user.password = hash_password(userform.new_password.data) save_user(user) flash(_(u'Information updated')) else: usererrors.append(_(u'Invalid password')) if userform.errors: for key, value in userform.errors.items(): usererrors.append(key + ': ' + value[0]) return render_template('user.html', userform=userform, usererrors=usererrors)
def __process_pending(troika): if troika.get_phase() == 'pending' and \ troika.lead is not None and \ troika.first_learner is not None and \ troika.second_learner is not None: troika.pended = datetime.now() if activation_ready(troika): __process_activation(troika) flash (_(u"Troika activated!")) else: if not app.config.get('MAIL_SKIP'): # Send message to all three participants msg = __get_troika_message(_(u"Troika \"%(title)s\" is just about to be born!", title=troika.title), troika) msg.body = _(u"Congratulations! The Troika \"%(title)s\":", title=troika.title) msg.body += "\n\n" + url_for('troika', troika_id=troika.id, _external=True) msg.body += "\n\n" msg.body += _(u"has now all three participants!") msg.body += "\n\n" msg.body += _(u"Your job now is to:") msg.body += "\n" msg.body += _(u"1. decide on the remaining open details for the Troika,") msg.body += _(u"2. go to the Troika page and press \"Edit Troika\" (visible for the lead and creator),") msg.body += _(u"3. add the missing information and press \"Save Troika\".") msg.body += "\n\n" msg.body += _(u"Get going!") msg.body += "\n\n" msg.body += _(u"[insert inspirational quote about balalaikas here]") msg.body += "\n\n" msg.body += __get_troika_message_signature() mail.send(msg)
def __process_activation(troika): troika.activated = datetime.now() if not app.config.get('MAIL_SKIP'): # Send message to all three participants msg = __get_troika_message(_(u"Troika \"%(title)s\" activated!", title=troika.title), troika) msg.body = _(u"Congratulations! The Troika \"%(title)s\":", title=troika.title) msg.body += "\n\n" + url_for('troika', troika_id=troika.id, _external=True) msg.body += "\n\n" msg.body += _(u"has now been activated. You can view the participants on the Troika page.") msg.body += "\n\n" msg.body += _(u"Happy learnings!") msg.body += "\n\n" msg.body += __get_troika_message_signature() mail.send(msg)
def feedback(): feedbackerrors = [] feedbackform = FeedbackForm() user = None given_feedback = [] if 'email' in session: user = get_user(session['email']) if user.role == 'admin': # For admins, the feedback is shown given_feedback = get_feedback() if feedbackform.validate_on_submit(): feedback = Feedback(created = datetime.now(), description=feedbackform.description.data, user=user) save_feedback(feedback) flash(_(u"Feedback saved. Thank you!")) return redirect(url_for('troikas')) if feedbackform.errors: for key, value in feedbackform.errors.items(): feedbackerrors.append(key + ': ' + value[0]) return render_template('feedback.html', feedbackform=feedbackform, feedbackerrors=feedbackerrors, given_feedback=given_feedback)
def logout(): if 'email' in session: session.pop('email', None) flash(_(u"You were logged out")) if 'destination' in session: session.pop('destination', None) return redirect(url_for('troikas'))
def __check_login(destination = None, url = None): if not 'email' in session: if url is None: url = url_for(destination) flash(_(u'You need to login or register first')) session['destination'] = url return url_for('login') return False
def get_redirect_target(): for target in request.values.get('next'), request.referrer: if not target: continue if is_safe_url(target): return target flash(_(u'Invalid redirect target'), 'error') return url_for('troikas')
def leave_troika(troika_id, troika_role): url = __check_login(url = url_for('leave_troika', troika_id = troika_id, troika_role = troika_role)) if url: return redirect(url) troika = get_troika(troika_id); user = get_user(session['email']) if troika.get_phase() != 'complete': if troika_role == '0': if troika.lead != user: flash(_(u"You are not the lead of this Troika"), 'error') return redirect(url_for('troika', troika_id=troika_id)) troika.lead = None save_troika(troika) flash(_(u"You are no longer the lead of %(title)s", title=troika.title)) return redirect(url_for('troika', troika_id=troika_id)) elif troika_role == '1': if troika.first_learner != user: flash(_(u"You are not the first learner of this Troika"), 'error') return redirect(url_for('troika', troika_id=troika_id)) troika.first_learner = None save_troika(troika) flash(_(u"You are no longer the first learner of %(title)s", title=troika.title)) return redirect(url_for('troika', troika_id=troika_id)) elif troika_role == '2': if troika.second_learner != user: flash(_(u"You are not the second learner of this Troika"), 'error') return redirect(url_for('troika', troika_id=troika_id)) troika.second_learner = None save_troika(troika) flash(_(u"You are no longer the second learner of %(title)s", title=troika.title)) return redirect(url_for('troika', troika_id=troika_id)) elif troika_role == '3': if user not in troika.participants: flash(_(u"You are not participating in the Troika"), 'error') return redirect(url_for('troika', troika_id=troika_id)) troika.participants.remove(user) save_troika(troika) flash(_(u"You are no longer participating in %(title)s", title=troika.title)) return redirect(url_for('troika', troika_id=troika_id)) else: flash(_(u"Unknown Troika role: %(role)s", role = troika_role), 'error') return redirect(url_for('troika', troika_id=troika_id)) else: flash(_(u"You can not leave a Troika that is complete"), 'error') return redirect(url_for('troika', troika_id=troika_id))
def activate_troika(troika_id): url = __check_login(url = url_for('activate_troika', troika_id = troika_id)) if url: return redirect(url) troika = get_troika(troika_id); user = get_user(session['email']) if activatable(user, troika, app.config.get('ACTIVATABLE_BEFORE_THREE')): if troika.start_time < datetime.now() and user.role != 'admin': flash(_(u'Start time is in the past, change it before activating Troika'), 'error') return redirect(url_for('troika', troika_id=troika_id)) __process_activation(troika) save_troika(troika) flash(_(u"Troika %(title)s activated", title=troika.title)) return redirect(url_for('troika', troika_id=troika_id)) else: flash(_(u'Troika can only be activated by the creator or lead after all required information is set'), 'error') return redirect(url_for('troika', troika_id=troika_id))
def login(): loginerrors = [] regerrors = [] regform = RegistrationForm(prefix="register") loginform = LoginForm(prefix="login") if loginform.email.data and loginform.validate_on_submit(): user = validate_login(loginform.email.data, loginform.password.data) if (user != False): session['email'] = user.email session['language'] = user.preferred_language flash(_(u'You were logged in')) destination = url_for('troikas') if 'destination' in session: destination = session['destination'] session.pop('destination', None) return redirect(destination) else: loginerrors.append(_(u'Invalid email/password')) if loginform.errors: for key, value in loginform.errors.items(): loginerrors.append(key + ': ' + value[0]) forgotform = ForgotForm() if regform.email.data and regform.validate_on_submit(): if (user_exists(email=regform.email.data, alias=regform.alias.data)): regerrors.append(_(u'User with given email or alias already exists')) else: if regform.alias.data == "": regform.alias.data = None register(regform.first_name.data, regform.last_name.data, regform.alias.data, regform.email.data, regform.password.data); session['email'] = regform.email.data flash(_(u'Registration successful, you were logged in')) destination = url_for('troikas') if 'destination' in session: destination = session['destination'] session.pop('destination', None) return redirect(destination) if regform.errors: for key, value in regform.errors.items(): regerrors.append(key + ': ' + value[0]) return render_template('login.html', loginform=loginform, forgotform=forgotform, regform=regform, loginerrors=loginerrors, regerrors=regerrors)
def reset(reset_key): user = get_user_by_reset_key(reset_key) if user is None: flash(_(u'Invalid password reset link'), 'error') return redirect(url_for('troikas')) resetform = ResetForm() reseterrors = [] if resetform.validate_on_submit(): user.password = hash_password(resetform.password.data) user.password_reset_key = None user.password_reset_expire = None session['email'] = user.email save_user(user) flash(_(u'Password reset successful, you were logged in')) return redirect(url_for('troikas')) if resetform.errors: for key, value in resetform.errors.items(): reseterrors.append(key + ': ' + value[0]) return render_template('reset.html', resetform=resetform, reseterrors=reseterrors)
def create_troika(): url = __check_login('create_troika') if url: return redirect(url) troikaerrors = [] troikaform = TroikaForm(prefix="troika") if troikaform.validate_on_submit(): user = get_user(session['email']) # Validate times if troikaform.start_date.data is not None and (troikaform.start_time_hours.data is None or troikaform.start_time_minutes.data is None or troikaform.duration.data is None): troikaerrors.append(_(u"When a date is set, you must also give values for hours, minutes and duration")) else: start_time = __get_start_datetime(troikaform.start_date.data, troikaform.start_time_hours.data, troikaform.start_time_minutes.data) if start_time is not None and start_time < datetime.now(): troikaerrors.append(_(u"Start time for the Troika must be in the future")) else: troika = Troika(created = datetime.now(), title=troikaform.title.data, description=troikaform.description.data, country='FI', region=None, area_id=None, campus_id=None, address=troikaform.address.data if troikaform.address.data != "" else None, address_addendum=troikaform.address_addendum.data if troikaform.address_addendum.data != "" else None, language=troikaform.language.data, start_time=start_time, end_time=__get_end_datetime(start_time, troikaform.duration.data), max_participants=troikaform.max_participants.data, creator=user) if troikaform.creator_role.data == 'lead': troika.lead = user else: troika.first_learner = user save_troika(troika) flash(_(u"Troika Created")) return redirect(url_for('troika', troika_id=troika.id)) if troikaform.errors: for key, value in troikaform.errors.items(): troikaerrors.append(key + ': ' + value[0]) return render_template('edit_troika.html', troikaform=troikaform, troikaerrors=troikaerrors, access='create')
def troika(troika_id): troika = get_troika(troika_id); access = False activate = False user = None if 'email' in session: user = get_user(session['email']) access = get_troika_access_right(user, troika) activate = activatable(user, troika, app.config.get('ACTIVATABLE_BEFORE_THREE')) troikaform = TroikaForm(language=troika.language) language_name = [item for item in troikaform.language.choices if item[0] == troika.language][0][1] address_text = troika.address if address_text is None: address_text = troika.address_addendum elif troika.address_addendum is not None: address_text += " - " + troika.address_addendum if address_text is None: address_text = _(u'Not set') entry = {'access': access, 'activate': activate, 'id': troika.id, 'phase': troika.get_phase(), 'title': troika.title, 'description': Markup(markdown.markdown(troika.description)), 'address': address_text, 'language': language_name, 'start_time': __get_formatted_datetime(troika.start_time,"%d.%m.%Y %H:%M") if troika.start_time is not None else _(u"Not set"), 'end_time': __get_formatted_datetime(troika.end_time,"%d.%m.%Y %H:%M") if troika.end_time is not None else _(u"Not set"), 'max_participants': troika.max_participants if troika.max_participants is not None else _(u"Not set"), 'is_full': __is_full(troika), 'participating': __participating(user, troika), 'lead': __get_display_name(troika.lead) if troika.lead != None else None, 'first_learner': __get_display_name(troika.first_learner) if troika.first_learner != None else None, 'second_learner': __get_display_name(troika.second_learner) if troika.second_learner != None else None, 'participants': [dict(id=participant.id, \ full_name=__get_display_name(participant)) \ for participant in troika.participants] if troika.participants is not None else None } inviteform_lead = InviteForm(role='0', troika_id = troika.id) inviteform_first = InviteForm(role='1', troika_id = troika.id) inviteform_second = InviteForm(role='2', troika_id = troika.id) inviteform_participant = InviteForm(role='3', troika_id = troika.id) # show the troika with the given id return render_template('troika.html', troika=entry, inviteform_lead=inviteform_lead, inviteform_first=inviteform_first, inviteform_second=inviteform_second, inviteform_participant=inviteform_participant)
def change_language(): langform = LanguageForm(prefix="language") if langform.validate(): if not 'language' in session or session['language'] != langform.language.data: session['language'] = langform.language.data # Also change the user language in the database, to make the change persistent if 'email' in session: user = get_user(session['email']) user.preferred_language = session['language'] save_user(user) else: flash(_(u'Invalid language form') + ': ' + ', '.join((key + ': ' + value[0]) for key, value in langform.errors.items()), 'error') return redirect(get_redirect_target())
def forgot(): forgotform = ForgotForm() if forgotform.validate(): reset_link = generate_password_reset_link(forgotform.email.data) if reset_link is None: flash(_(u'Could not find user with given email'), 'error') else: msg = Message(_(u"Troikalearning.org password reset"), sender = ("Troika Webmaster", "*****@*****.**"), recipients=[forgotform.email.data]) msg.body = _("Go to the following link to reset your password in the troikalearning.org website:") msg.body += "\n\n" + reset_link msg.body += "\n\n" msg.body += _("If you did not ask for your password to be reset, you can ignore this message.") msg.body += "\n\n" msg.body += __get_troika_message_signature() mail.send(msg) flash(_(u'Password reset instructions sent to %(email)s', email = forgotform.email.data)) else: flash(_(u"Invalid forgot form") + ': ' + ', '.join((key + ': ' + value[0]) for key, value in forgotform.errors.items()), 'error') return redirect(get_redirect_target())
def __get_troika_message_signature(): signature = "--\n" signature += _(u"Troika Team") + "\n" signature += _(u"Salla, Olli, Petro and Timo") + "\n" signature += "http://troikalearning.org" return signature
def join_troika(troika_id, troika_role): url = __check_login(url = url_for('join_troika', troika_id = troika_id, troika_role = troika_role)) if url: return redirect(url) troika = get_troika(troika_id); user = get_user(session['email']) if not __participating(user, troika): if troika_role == '0': if troika.lead is not None: flash(_(u"The Troika already has a lead"), 'error') return redirect(url_for('troika', troika_id=troika_id)) troika.lead = user __process_pending(troika) save_troika(troika) flash(_(u"You are now the lead of %(title)s", title=troika.title)) return redirect(url_for('troika', troika_id=troika_id)) elif troika_role == '1': if troika.first_learner is not None: flash(_(u"The Troika already has a first learner"), 'error') return redirect(url_for('troika', troika_id=troika_id)) troika.first_learner = user __process_pending(troika) save_troika(troika) flash(_(u"You are now the first learner of %(title)s", title=troika.title)) return redirect(url_for('troika', troika_id=troika_id)) elif troika_role == '2': if troika.second_learner is not None: flash(_(u"The Troika already has a second learner"), 'error') return redirect(url_for('troika', troika_id=troika_id)) troika.second_learner = user __process_pending(troika) save_troika(troika) flash(_(u"You are now the second learner of %(title)s", title=troika.title)) return redirect(url_for('troika', troika_id=troika_id)) elif troika_role == '3': if user in troika.participants: flash(_(u"You are already participating in the Troika"), 'error') return redirect(url_for('troika', troika_id=troika_id)) if __is_full(troika): flash(_(u"There is no more room in this Troika"), 'error') return redirect(url_for('troika', troika_id=troika_id)) troika.participants.append(user) save_troika(troika) flash(_(u"You are now participating in %(title)s", title=troika.title)) return redirect(url_for('troika', troika_id=troika_id)) else: flash(_(u"Unknown Troika role: %(role)", role=troika_role), 'error') return redirect(url_for('troika', troika_id=troika_id)) else: flash(_(u"You are already participating in the Troika"), 'error') return redirect(url_for('troika', troika_id=troika_id))
def edit_troika(troika_id): url = __check_login(url = url_for('edit_troika', troika_id = troika_id)) if url: return redirect(url) troikaerrors = [] troikaform = TroikaForm(prefix="troika") # Find out if the logged in user has rights to edit/delete troika = get_troika(troika_id); user = get_user(session['email']) access = get_troika_access_right(user, troika) if not access: flash(_(u'Only the creator or the lead can edit the Troika'), 'error') return redirect(url_for('troika', troika_id=troika_id)) if request.method == 'GET': # Add default values troikaform.title.data = troika.title troikaform.description.data = troika.description troikaform.address.data = troika.address troikaform.address_addendum.data = troika.address_addendum troikaform.language.data = troika.language troikaform.start_date.data = troika.start_time troikaform.start_time_hours.data = __get_formatted_datetime(troika.start_time,"%H") troikaform.start_time_minutes.data = __get_formatted_datetime(troika.start_time,"%M") troikaform.duration.data = __get_duration(troika.start_time, troika.end_time) troikaform.max_participants.data = troika.max_participants elif troikaform.validate_on_submit(): if request.form["action"] == _(u"Save Troika"): # Validate times if troikaform.start_date.data is not None and (troikaform.start_time_hours.data is None or troikaform.start_time_minutes.data is None or troikaform.duration.data is None): troikaerrors.append(_(u"When a date is set, you must also give values for hours, minutes and duration")) else: start_time = __get_start_datetime(troikaform.start_date.data, troikaform.start_time_hours.data, troikaform.start_time_minutes.data) if user.role != 'admin' and start_time is not None and start_time < datetime.now(): troikaerrors.append(_(u"Start time for the Troika must be in the future")) else: # Update info troika.title = troikaform.title.data troika.description = troikaform.description.data troika.address = troikaform.address.data if troikaform.address.data != "" else None troika.address_addendum = troikaform.address_addendum.data if troikaform.address_addendum.data != "" else None troika.language = troikaform.language.data troika.start_time = start_time troika.end_time = __get_end_datetime(troika.start_time, troikaform.duration.data) troika.max_participants = troikaform.max_participants.data # Activate automatically when all information is given if activation_ready(troika): __process_activation(troika) flash (_(u"Troika activated!")) save_troika(troika) flash(_(u'Troika saved')) return redirect(url_for('troika', troika_id=troika_id)) elif request.form["action"] == _(u"Delete Troika"): title = troika.title delete_troika(troika) flash(_(u"Troika \"%(title)s\" deleted", title=title)) return redirect(url_for('troikas')) if troikaform.errors: for key, value in troikaform.errors.items(): troikaerrors.append(key + ': ' + value[0]) return render_template('edit_troika.html', troikaform=troikaform, troikaerrors=troikaerrors, access=access)
def invite(): url = __check_login(url = get_redirect_target()) if url: return redirect(url) inviteform = InviteForm() if inviteform.validate(): user = get_user(session['email']) troika = get_troika(inviteform.troika_id.data) if troika is None: flash(_(u'Invalid Troika Id'), 'error') elif troika.get_phase() == 'complete': flash(_(u'Can not invite to a completed Troika'), 'error') else: msg = Message(_(u"Come join the Troika \"%(title)s\"!", title=troika.title), sender = ("Troika Webmaster", "*****@*****.**"), recipients=[inviteform.email.data]) msg.body = _("%(user)s thought you should join the Troika \"%(title)s\":", user = __get_display_name(user), title=troika.title) msg.body += "\n\n" + url_for('troika', troika_id=troika.id, _external=True) msg.body += "\n\n" role_string = None if inviteform.role.data == '0': if troika.lead is None: role_string = _("the lead") else: flash(_(u'Troika already has a lead'), 'error') elif inviteform.role.data == '1': if troika.first_learner is None: role_string = _("the first learner") else: flash(_(u'Troika already has a first learner'), 'error') elif inviteform.role.data == '2': if troika.second_learner is None: role_string = _("the second learner") else: flash(_(u'Troika already has a second learner'), 'error') elif inviteform.role.data == '3': role_string = _("a participant") else: flash(_(u'Invalid role: ') + 'inviteform.role', 'error') if role_string is not None: msg.body += _("as %(role)s.", role=role_string) msg.body += "\n\n" msg.body += _("What do you say?") + "\n\n" msg.body += __get_troika_message_signature() mail.send(msg) flash(_(u'Invite sent to %(email)s', email = inviteform.email.data)) else: flash(_(u"Invalid invite form") + ': ' + ', '.join((key + ': ' + value[0]) for key, value in inviteform.errors.items()), 'error') return redirect(get_redirect_target())