def reset_password_token(token): """ Get data for the recent activity sidebar (in base.html) """ recent = utils.get_recent_activity() """ A user who is currently logged in wouldn't have asked for password reset, so redirect to home """ if current_user.is_authenticated: return redirect(url_for('home')) """ Verifying token """ user = User.verify_password_reset_token(token) """ If the token is expired or invalid, redirect to the password reset request """ if not user: flash('Sorry, that token is invalid or has expired', 'warning') return redirect(url_for('reset_password_request')) """ Instantiate the reset password form """ form = ResetPasswordForm() if form.validate_on_submit(): """ Update DB user document with new password """ db.users.update_one({'username': user['username']}, {'$set': { 'password': form.password.data }}) """ Flash a success message """ flash(f'Your password has been updated! You can now log in.', 'success') return redirect(url_for('login')) return render_template('reset-password-token.html', title='Reset Password', form=form, recent=recent)
def login(): """ Get data for the recent activity sidebar (in base.html) """ recent = utils.get_recent_activity() """ If user is logged in, these routes are unnecessary and so redirect to home page """ if current_user.is_authenticated: return redirect(url_for('home')) """ Instantiate form """ form = LoginForm() if form.validate_on_submit(): user = db.users.find_one({'email': form.email.data}) if user and user['password'] == form.password.data: user_obj = User(username=user['username'], email=user['email'], bio=user['bio'], location=user['location'], level=user['level'], password=user['password']) login_user(user_obj, remember=form.remember.data) """ The following assures the user will be redirected to the page she wanted before being prompted to sign in (if prompted) """ next_page = request.args.get('next') if next_page: return redirect(next_page) else: return redirect(url_for('home')) else: flash('Login Unsuccessful. Please check email and password', 'danger') return render_template('login.html', title='Login', form=form, recent=recent)
def view_user_profile(user): """ Get data for the recent activity sidebar (in base.html) """ recent = utils.get_recent_activity() """ If a user is logged on and if the query name matches the logged on user's name, then serve a personal profile template """ if current_user.is_authenticated and user == current_user.username: image_file = url_for('static', filename='img/avatars/' + current_user.image_file) return render_template('your-profile.html', title='Your Profile', recent=recent, image_file=image_file) else: """ Otherwise pull queried user's data from DB, then serve a public profile template """ profile_data = db.users.find_one({'username': user}) """ If username is in db then serve public profile, otherwise serve missing profile page""" if profile_data is not None: image_file = url_for('static', filename='img/avatars/' + profile_data['image_file']) return render_template('profile.html', title='User Profile', profile_data=profile_data, recent=recent, image_file=image_file) else: return render_template('missing-profile.html', title='Missing profile', recent=recent)
def reset_password_request(): """ Get data for the recent activity sidebar (in base.html) """ recent = utils.get_recent_activity() """ A logged-in user hasn't forgotten their password, so is redirected to home page """ if current_user.is_authenticated: return redirect(url_for('home')) """ Instantiate request password form """ form = RequestResetPasswordForm() if form.validate_on_submit(): """ Get user data from DB """ user_data = db.users.find_one({'email': form.email.data}) """ Use user data to instantiate User object """ user = User(username=user_data['username'], email=user_data['email'], bio=user_data['bio'], location=user_data['location'], level=user_data['level'], password=user_data['password'], translations=user_data['translations'], favourites=user_data['favourites']) """ Send user email with link (and token!) to change password """ utils.send_reset_password_email(user) flash( 'You\'ve been sent an automated email. Please follow instructions to reset your password.', 'info') return redirect(url_for('login')) return render_template('reset-password-request.html', title='Reset Password', form=form, recent=recent)
def about(): """ Get data for the recent activity sidebar (in base.html) """ recent = utils.get_recent_activity() image_file = url_for('static', filename='img/sign.jpg') return render_template('about.html', title='About Us', recent=recent, image_file=image_file)
def street(street_name): """ Get data for the recent activity sidebar (in base.html) """ recent = utils.get_recent_activity() user = current_user query = street_name street = db.streets.find_one({'name_en': street_name}) return render_template('street.html', title='Street Details', street=street, user=user, recent=recent)
def edit_translation(street_name): """ Get data for the recent activity sidebar (in base.html) """ recent = utils.get_recent_activity() """ Collect street data from query """ user = current_user """ Call DB for street data """ street_data = db.streets.find_one({'name_en': street_name}) """ Extract target translation from translations array """ translation = [ translation for translation in street_data['translations'] if translation['username'] == user.username ] """ Converting list to dict object """ target_translation = translation[0] """ Instantiate edit translation form """ form = EditTranslationForm() """ If request method is GET, then prepopulate the edit form with data from target translation """ if request.method == 'GET': form.translation.data = target_translation['name_ga'] form.note.data = target_translation['note'] """ Analysing data to check which radio button to preselect """ if target_translation['src'] != target_translation['username']: form.source.data = 'other' form.src.data = target_translation['src'] else: form.source.data = 'user' """ If method is POST, then validate form and redirect back to the corresponding street page """ if form.validate_on_submit(): """ Get current time and add to form data """ current_date = datetime.now() """ Set src to user if no external source provided """ if form.source.data == 'user': form.src.data = current_user.username translation = Translation(name_ga=form.translation.data, date_posted=current_date, note=form.note.data, src=form.src.data, username=user.username, street_name=street_name) """ Update DB to edit translation """ translation.update_in_db() flash('Translation edited successfully.', 'success') return redirect(url_for('street', street_name=street_name)) return render_template("edit-translation.html", title='Edit translation', form=form, street=street_name, user=user, recent=recent)
def home(): """ Get data for the recent activity sidebar (in base.html) """ recent = utils.get_recent_activity() form = StreetSelectForm() form.select.choices = [(item['name_en'], item['name_en']) for item in db.streets.find()] if form.validate_on_submit(): queryDB = db.streets.find_one({'name_en': form.select.data}) street_data = { '_id': str(queryDB['_id']), 'name_en': queryDB['name_en'], 'postcode': queryDB['postcode'], 'translations': queryDB['translations'], 'pos': queryDB['pos'] } """ If street request is valid then return appropriate street page """ return redirect(url_for('street', street_name=street_data['name_en'])) return render_template('home.html', form=form, recent=recent)
def add_translation(street_name): """ Get data for the recent activity sidebar (in base.html) """ recent = utils.get_recent_activity() user = current_user """ Get data from DB """ street = db.streets.find_one({'name_en': street_name}) """ Check if user has already contributed a translation for this street - if so, flash warning message """ for obj in street['translations']: if obj['username'] == user.username: flash( 'Translations are limited to one translation per street per user.', 'warning') return redirect(url_for('street', street_name=street['name_en'])) """ Instantiate translation form """ form = TranslationForm() if form.validate_on_submit(): """ Get current time and add to form data """ current_date = datetime.now() """ Set src to user if no external source provided """ if form.source.data == 'user': form.src.data = current_user.username translation = Translation(name_ga=form.translation.data, date_posted=current_date, note=form.note.data, src=form.src.data, username=user.username, street_name=street['name_en']) """ Add translation to DB (streets collection) """ translation.add_to_db() """ Add translation reference to corresponding user document (users collection) """ translation.update_in_user_db() flash('Translation added successfully.', 'success') return redirect(url_for('street', street_name=street['name_en'])) return render_template('add-translation.html', title='Translate Street', form=form, street=street_name, user=user, recent=recent)
def register(): """ Get data for the recent activity sidebar (in base.html) """ recent = utils.get_recent_activity() """ If user is logged in, these routes are unnecessary and so redirect to home page""" if current_user.is_authenticated: return redirect(url_for('home')) """ Instantiate form """ form = RegistrationForm() if form.validate_on_submit(): user = User(username=form.username.data, email=form.email.data, bio=form.bio.data, location=form.location.data, level=form.level.data, password=form.password.data) user.add_to_db() flash(f'Account created for {form.username.data}! You can now log in.', 'success') return redirect(url_for('login')) return render_template('register.html', title='Register', form=form, recent=recent)
def edit_profile(): """ Get data for the recent activity sidebar (in base.html) """ recent = utils.get_recent_activity() """ Set avatar image from static avatars folder (in the future this will be automated to depend on skill level) """ image_file = url_for('static', filename='img/avatars/' + current_user.image_file) """ See method below to discern between the following forms """ form = EditProfileForm() form2 = DeleteAccountForm() if request.method == 'GET': form.email.data = current_user.email form.bio.data = current_user.bio form.location.data = current_user.location form.level.data = current_user.level if request.method == 'POST': """ If edit form is posted """ if 'submit' in request.form: """ If user edits email address (which is used for login), force relogin after edit """ if form.email.data != current_user.email: db.users.update_one({'username': current_user.username}, { '$set': { 'email': form.email.data, 'bio': form.bio.data, 'location': form.location.data, 'level': form.level.data } }) flash( f'You\'ve successfully updated your profile. Please log in again.', 'success') return redirect(url_for('logout')) """ If user doesn't edit email adderss, then do not force relogin, just update profile """ else: db.users.update_one({'username': current_user.username}, { '$set': { 'email': form.email.data, 'bio': form.bio.data, 'location': form.location.data, 'level': form.level.data } }) flash(f'You\'ve successfully updated your profile.', 'success') return redirect( url_for('view_user_profile', user=current_user.username)) """ else if delete account form is posted """ else: """ If user has contributed street translations, change the username associated with each to 'account deleted' in the 'streets' collection """ db.streets.update_many( {'translations.username': current_user.username}, {'$set': { 'translations.$.username': '******' }}) """ In the 'users' collection, remove the user document """ db.users.delete_one({'username': current_user.username}) flash(f'You\'ve successfully deleted your account.', 'success') """ Account deleted so force logout """ return redirect(url_for('logout')) return render_template('edit-profile.html', title='Edit profile', image_file=image_file, recent=recent, form=form, form2=form2)