Example #1
0
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)
Example #2
0
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)
Example #3
0
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)
Example #4
0
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)
Example #5
0
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'))
Example #6
0
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
Example #7
0
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')
Example #8
0
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))
Example #9
0
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))
Example #10
0
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)
Example #11
0
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)
Example #12
0
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')
Example #13
0
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)
Example #14
0
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())
Example #15
0
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())
Example #16
0
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
Example #17
0
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))
Example #18
0
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)
Example #19
0
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())