Allow translating flash messages

This commit is contained in:
rubenwardy 2022-01-07 21:46:16 +00:00
parent c4dd380218
commit dcd7e31738
11 changed files with 99 additions and 89 deletions

View File

@ -96,7 +96,7 @@ def flatpage(path):
def check_for_ban(): def check_for_ban():
if current_user.is_authenticated: if current_user.is_authenticated:
if current_user.rank == models.UserRank.BANNED: if current_user.rank == models.UserRank.BANNED:
flash("You have been banned.", "danger") flash(gettext("You have been banned."), "danger")
logout_user() logout_user()
return redirect(url_for("users.login")) return redirect(url_for("users.login"))
elif current_user.rank == models.UserRank.NOT_JOINED: elif current_user.rank == models.UserRank.NOT_JOINED:

View File

@ -15,6 +15,7 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
from flask import Blueprint from flask import Blueprint
from flask_babel import gettext
bp = Blueprint("github", __name__) bp = Blueprint("github", __name__)
@ -42,7 +43,7 @@ def view_permissions():
def callback(oauth_token): def callback(oauth_token):
next_url = request.args.get("next") next_url = request.args.get("next")
if oauth_token is None: if oauth_token is None:
flash("Authorization failed [err=gh-oauth-login-failed]", "danger") flash(gettext("Authorization failed [err=gh-oauth-login-failed]"), "danger")
return redirect(url_for("users.login")) return redirect(url_for("users.login"))
# Get Github username # Get Github username
@ -58,21 +59,21 @@ def callback(oauth_token):
if userByGithub is None: if userByGithub is None:
current_user.github_username = username current_user.github_username = username
db.session.commit() db.session.commit()
flash("Linked github to account", "success") flash(gettext("Linked github to account"), "success")
return redirect(url_for("homepage.home")) return redirect(url_for("homepage.home"))
else: else:
flash("Github account is already associated with another user", "danger") flash(gettext("Github account is already associated with another user"), "danger")
return redirect(url_for("homepage.home")) return redirect(url_for("homepage.home"))
# If not logged in, log in # If not logged in, log in
else: else:
if userByGithub is None: if userByGithub is None:
flash("Unable to find an account for that Github user", "danger") flash(gettext("Unable to find an account for that Github user"), "danger")
return redirect(url_for("users.claim_forums")) return redirect(url_for("users.claim_forums"))
ret = login_user_set_active(userByGithub, remember=True) ret = login_user_set_active(userByGithub, remember=True)
if ret is None: if ret is None:
flash("Authorization failed [err=gh-login-failed]", "danger") flash(gettext("Authorization failed [err=gh-login-failed]"), "danger")
return redirect(url_for("users.login")) return redirect(url_for("users.login"))
addAuditLog(AuditSeverity.USER, userByGithub, "Logged in using GitHub OAuth", addAuditLog(AuditSeverity.USER, userByGithub, "Logged in using GitHub OAuth",

View File

@ -18,7 +18,7 @@
from urllib.parse import quote as urlescape from urllib.parse import quote as urlescape
from flask import render_template from flask import render_template
from flask_babel import lazy_gettext from flask_babel import lazy_gettext, gettext
from flask_wtf import FlaskForm from flask_wtf import FlaskForm
from flask_login import login_required from flask_login import login_required
from sqlalchemy import or_, func from sqlalchemy import or_, func
@ -156,16 +156,16 @@ def view(package):
if package.state != PackageState.APPROVED and package.forums is not None: if package.state != PackageState.APPROVED and package.forums is not None:
errors = [] errors = []
if Package.query.filter(Package.forums==package.forums, Package.state!=PackageState.DELETED).count() > 1: if Package.query.filter(Package.forums==package.forums, Package.state!=PackageState.DELETED).count() > 1:
errors.append("<b>Error: Another package already uses this forum topic!</b>") errors.append("<b>" + gettext("Error: Another package already uses this forum topic!") + "</b>")
topic_error_lvl = "danger" topic_error_lvl = "danger"
topic = ForumTopic.query.get(package.forums) topic = ForumTopic.query.get(package.forums)
if topic is not None: if topic is not None:
if topic.author != package.author: if topic.author != package.author:
errors.append("<b>Error: Forum topic author doesn't match package author.</b>") errors.append("<b>" + gettext("Error: Forum topic author doesn't match package author.") + "</b>")
topic_error_lvl = "danger" topic_error_lvl = "danger"
elif package.type != PackageType.TXP: elif package.type != PackageType.TXP:
errors.append("Warning: Forum topic not found. This may happen if the topic has only just been created.") errors.append(gettext("Warning: Forum topic not found. This may happen if the topic has only just been created."))
topic_error = "<br />".join(errors) topic_error = "<br />".join(errors)
@ -212,7 +212,7 @@ def download(package):
not "text/html" in request.accept_mimetypes: not "text/html" in request.accept_mimetypes:
return "", 204 return "", 204
else: else:
flash("No download available.", "danger") flash(gettext("No download available."), "danger")
return redirect(package.getURL("packages.view")) return redirect(package.getURL("packages.view"))
else: else:
return redirect(release.getDownloadURL()) return redirect(release.getDownloadURL())
@ -261,11 +261,11 @@ def create_edit(author=None, name=None):
else: else:
author = User.query.filter_by(username=author).first() author = User.query.filter_by(username=author).first()
if author is None: if author is None:
flash("Unable to find that user", "danger") flash(gettext("Unable to find that user"), "danger")
return redirect(url_for("packages.create_edit")) return redirect(url_for("packages.create_edit"))
if not author.checkPerm(current_user, Permission.CHANGE_AUTHOR): if not author.checkPerm(current_user, Permission.CHANGE_AUTHOR):
flash("Permission denied", "danger") flash(gettext("Permission denied"), "danger")
return redirect(url_for("packages.create_edit")) return redirect(url_for("packages.create_edit"))
else: else:
@ -303,7 +303,7 @@ def create_edit(author=None, name=None):
if package.state == PackageState.READY_FOR_REVIEW: if package.state == PackageState.READY_FOR_REVIEW:
Package.query.filter_by(name=form["name"].data, author_id=author.id).delete() Package.query.filter_by(name=form["name"].data, author_id=author.id).delete()
else: else:
flash("Package already exists!", "danger") flash(gettext("Package already exists!"), "danger")
return redirect(url_for("packages.create_edit")) return redirect(url_for("packages.create_edit"))
package = Package() package = Package()
@ -363,7 +363,7 @@ def move_to_state(package):
abort(400) abort(400)
if not package.canMoveToState(current_user, state): if not package.canMoveToState(current_user, state):
flash("You don't have permission to do that", "danger") flash(gettext("You don't have permission to do that"), "danger")
return redirect(package.getURL("packages.view")) return redirect(package.getURL("packages.view"))
package.state = state package.state = state
@ -391,7 +391,7 @@ def move_to_state(package):
db.session.commit() db.session.commit()
if package.state == PackageState.CHANGES_NEEDED: if package.state == PackageState.CHANGES_NEEDED:
flash("Please comment what changes are needed in the review thread", "warning") flash(gettext("Please comment what changes are needed in the review thread"), "warning")
if package.review_thread: if package.review_thread:
return redirect(package.review_thread.getViewURL()) return redirect(package.review_thread.getViewURL())
else: else:
@ -410,7 +410,7 @@ def remove(package):
if "delete" in request.form: if "delete" in request.form:
if not package.checkPerm(current_user, Permission.DELETE_PACKAGE): if not package.checkPerm(current_user, Permission.DELETE_PACKAGE):
flash("You don't have permission to do that.", "danger") flash(gettext("You don't have permission to do that."), "danger")
return redirect(package.getURL("packages.view")) return redirect(package.getURL("packages.view"))
package.state = PackageState.DELETED package.state = PackageState.DELETED
@ -421,12 +421,12 @@ def remove(package):
addAuditLog(AuditSeverity.EDITOR, current_user, msg, url) addAuditLog(AuditSeverity.EDITOR, current_user, msg, url)
db.session.commit() db.session.commit()
flash("Deleted package", "success") flash(gettext("Deleted package"), "success")
return redirect(url) return redirect(url)
elif "unapprove" in request.form: elif "unapprove" in request.form:
if not package.checkPerm(current_user, Permission.UNAPPROVE_PACKAGE): if not package.checkPerm(current_user, Permission.UNAPPROVE_PACKAGE):
flash("You don't have permission to do that.", "danger") flash(gettext("You don't have permission to do that."), "danger")
return redirect(package.getURL("packages.view")) return redirect(package.getURL("packages.view"))
package.state = PackageState.WIP package.state = PackageState.WIP
@ -437,7 +437,7 @@ def remove(package):
db.session.commit() db.session.commit()
flash("Unapproved package", "success") flash(gettext("Unapproved package"), "success")
return redirect(package.getURL("packages.view")) return redirect(package.getURL("packages.view"))
else: else:
@ -455,7 +455,7 @@ class PackageMaintainersForm(FlaskForm):
@is_package_page @is_package_page
def edit_maintainers(package): def edit_maintainers(package):
if not package.checkPerm(current_user, Permission.EDIT_MAINTAINERS): if not package.checkPerm(current_user, Permission.EDIT_MAINTAINERS):
flash("You do not have permission to edit maintainers", "danger") flash(gettext("You do not have permission to edit maintainers"), "danger")
return redirect(package.getURL("packages.view")) return redirect(package.getURL("packages.view"))
form = PackageMaintainersForm(formdata=request.form) form = PackageMaintainersForm(formdata=request.form)
@ -505,10 +505,10 @@ def edit_maintainers(package):
@is_package_page @is_package_page
def remove_self_maintainers(package): def remove_self_maintainers(package):
if not current_user in package.maintainers: if not current_user in package.maintainers:
flash("You are not a maintainer", "danger") flash(gettext("You are not a maintainer"), "danger")
elif current_user == package.author: elif current_user == package.author:
flash("Package owners cannot remove themselves as maintainers", "danger") flash(gettext("Package owners cannot remove themselves as maintainers"), "danger")
else: else:
package.maintainers.remove(current_user) package.maintainers.remove(current_user)

View File

@ -16,6 +16,7 @@
from flask import * from flask import *
from flask_babel import gettext
from flask_login import login_required from flask_login import login_required
from flask_wtf import FlaskForm from flask_wtf import FlaskForm
from wtforms import * from wtforms import *
@ -278,7 +279,7 @@ def update_config(package):
abort(403) abort(403)
if not package.repo: if not package.repo:
flash("Please add a Git repository URL in order to set up automatic releases", "danger") flash(gettext("Please add a Git repository URL in order to set up automatic releases"), "danger")
return redirect(package.getURL("packages.create_edit")) return redirect(package.getURL("packages.create_edit"))
form = PackageUpdateConfigFrom(obj=package.update_config) form = PackageUpdateConfigFrom(obj=package.update_config)
@ -294,7 +295,7 @@ def update_config(package):
if form.validate_on_submit(): if form.validate_on_submit():
if form.disable.data: if form.disable.data:
flash("Deleted update configuration", "success") flash(gettext("Deleted update configuration"), "success")
if package.update_config: if package.update_config:
db.session.delete(package.update_config) db.session.delete(package.update_config)
db.session.commit() db.session.commit()
@ -302,7 +303,7 @@ def update_config(package):
set_update_config(package, form) set_update_config(package, form)
if not form.disable.data and package.releases.count() == 0: if not form.disable.data and package.releases.count() == 0:
flash("Now, please create an initial release", "success") flash(gettext("Now, please create an initial release"), "success")
return redirect(package.getURL("packages.create_release")) return redirect(package.getURL("packages.create_release"))
return redirect(package.getURL("packages.list_releases")) return redirect(package.getURL("packages.list_releases"))

View File

@ -15,6 +15,8 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
from collections import namedtuple from collections import namedtuple
from flask_babel import gettext
from . import bp from . import bp
from flask import * from flask import *
@ -47,7 +49,7 @@ class ReviewForm(FlaskForm):
@is_package_page @is_package_page
def review(package): def review(package):
if current_user in package.maintainers: if current_user in package.maintainers:
flash("You can't review your own package!", "danger") flash(gettext("You can't review your own package!"), "danger")
return redirect(package.getURL("packages.view")) return redirect(package.getURL("packages.view"))
review = PackageReview.query.filter_by(package=package, author=current_user).first() review = PackageReview.query.filter_by(package=package, author=current_user).first()
@ -151,7 +153,7 @@ def delete_review(package):
def handle_review_vote(package: Package, review_id: int): def handle_review_vote(package: Package, review_id: int):
if current_user in package.maintainers: if current_user in package.maintainers:
flash("You can't vote on the reviews on your own package!", "danger") flash(gettext("You can't vote on the reviews on your own package!"), "danger")
return return
review: PackageReview = PackageReview.query.get(review_id) review: PackageReview = PackageReview.query.get(review_id)
@ -159,7 +161,7 @@ def handle_review_vote(package: Package, review_id: int):
abort(404) abort(404)
if review.author == current_user: if review.author == current_user:
flash("You can't vote on your own reviews!", "danger") flash(gettext("You can't vote on your own reviews!"), "danger")
return return
is_positive = isYes(request.form["is_positive"]) is_positive = isYes(request.form["is_positive"])

View File

@ -16,6 +16,7 @@
from flask import * from flask import *
from flask_babel import gettext
from flask_wtf import FlaskForm from flask_wtf import FlaskForm
from flask_login import login_required from flask_login import login_required
from wtforms import * from wtforms import *
@ -135,7 +136,7 @@ def delete_screenshot(package, id):
abort(404) abort(404)
if not package.checkPerm(current_user, Permission.ADD_SCREENSHOTS): if not package.checkPerm(current_user, Permission.ADD_SCREENSHOTS):
flash("Permission denied", "danger") flash(gettext("Permission denied"), "danger")
return redirect(url_for("homepage.home")) return redirect(url_for("homepage.home"))
if package.cover_image == screenshot: if package.cover_image == screenshot:

View File

@ -14,6 +14,7 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
from flask import * from flask import *
from flask_babel import gettext
from app.tasks.webhooktasks import post_discord_webhook from app.tasks.webhooktasks import post_discord_webhook
@ -59,9 +60,9 @@ def subscribe(id):
abort(404) abort(404)
if current_user in thread.watchers: if current_user in thread.watchers:
flash("Already subscribed!", "success") flash(gettext("Already subscribed!"), "success")
else: else:
flash("Subscribed to thread", "success") flash(gettext("Subscribed to thread"), "success")
thread.watchers.append(current_user) thread.watchers.append(current_user)
db.session.commit() db.session.commit()
@ -76,11 +77,11 @@ def unsubscribe(id):
abort(404) abort(404)
if current_user in thread.watchers: if current_user in thread.watchers:
flash("Unsubscribed!", "success") flash(gettext("Unsubscribed!"), "success")
thread.watchers.remove(current_user) thread.watchers.remove(current_user)
db.session.commit() db.session.commit()
else: else:
flash("Already not subscribed!", "success") flash(gettext("Already not subscribed!"), "success")
return redirect(thread.getViewURL()) return redirect(thread.getViewURL())
@ -99,10 +100,10 @@ def set_lock(id):
msg = None msg = None
if thread.locked: if thread.locked:
msg = "Locked thread '{}'".format(thread.title) msg = "Locked thread '{}'".format(thread.title)
flash("Locked thread", "success") flash(gettext("Locked thread"), "success")
else: else:
msg = "Unlocked thread '{}'".format(thread.title) msg = "Unlocked thread '{}'".format(thread.title)
flash("Unlocked thread", "success") flash(gettext("Unlocked thread"), "success")
addNotification(thread.watchers, current_user, NotificationType.OTHER, msg, thread.getViewURL(), thread.package) addNotification(thread.watchers, current_user, NotificationType.OTHER, msg, thread.getViewURL(), thread.package)
addAuditLog(AuditSeverity.MODERATION, current_user, msg, thread.getViewURL(), thread.package) addAuditLog(AuditSeverity.MODERATION, current_user, msg, thread.getViewURL(), thread.package)
@ -151,7 +152,7 @@ def delete_reply(id):
abort(404) abort(404)
if thread.replies[0] == reply: if thread.replies[0] == reply:
flash("Cannot delete thread opening post!", "danger") flash(gettext("Cannot delete thread opening post!"), "danger")
return redirect(thread.getViewURL()) return redirect(thread.getViewURL())
if not reply.checkPerm(current_user, Permission.DELETE_REPLY): if not reply.checkPerm(current_user, Permission.DELETE_REPLY):
@ -220,11 +221,11 @@ def view(id):
comment = request.form["comment"] comment = request.form["comment"]
if not thread.checkPerm(current_user, Permission.COMMENT_THREAD): if not thread.checkPerm(current_user, Permission.COMMENT_THREAD):
flash("You cannot comment on this thread", "danger") flash(gettext("You cannot comment on this thread"), "danger")
return redirect(thread.getViewURL()) return redirect(thread.getViewURL())
if not current_user.canCommentRL(): if not current_user.canCommentRL():
flash("Please wait before commenting again", "danger") flash(gettext("Please wait before commenting again"), "danger")
return redirect(thread.getViewURL()) return redirect(thread.getViewURL())
if 2000 >= len(comment) > 3: if 2000 >= len(comment) > 3:
@ -252,7 +253,7 @@ def view(id):
return redirect(thread.getViewURL()) return redirect(thread.getViewURL())
else: else:
flash("Comment needs to be between 3 and 2000 characters.") flash(gettext("Comment needs to be between 3 and 2000 characters."), "danger")
return render_template("threads/view.html", thread=thread) return render_template("threads/view.html", thread=thread)
@ -273,7 +274,7 @@ def new():
if "pid" in request.args: if "pid" in request.args:
package = Package.query.get(int(request.args.get("pid"))) package = Package.query.get(int(request.args.get("pid")))
if package is None: if package is None:
flash("Unable to find that package!", "danger") flash(gettext("Unable to find that package!"), "danger")
# Don't allow making orphan threads on approved packages for now # Don't allow making orphan threads on approved packages for now
if package is None: if package is None:
@ -287,16 +288,16 @@ def new():
# Check that user can make the thread # Check that user can make the thread
if not package.checkPerm(current_user, Permission.CREATE_THREAD): if not package.checkPerm(current_user, Permission.CREATE_THREAD):
flash("Unable to create thread!", "danger") flash(gettext("Unable to create thread!"), "danger")
return redirect(url_for("homepage.home")) return redirect(url_for("homepage.home"))
# Only allow creating one thread when not approved # Only allow creating one thread when not approved
elif is_review_thread and package.review_thread is not None: elif is_review_thread and package.review_thread is not None:
flash("A review thread already exists!", "danger") flash(gettext("A review thread already exists!"), "danger")
return redirect(package.review_thread.getViewURL()) return redirect(package.review_thread.getViewURL())
elif not current_user.canOpenThreadRL(): elif not current_user.canOpenThreadRL():
flash("Please wait before opening another thread", "danger") flash(gettext("Please wait before opening another thread"), "danger")
if package: if package:
return redirect(package.getURL("packages.view")) return redirect(package.getURL("packages.view"))

View File

@ -17,6 +17,7 @@
from flask import * from flask import *
from flask_babel import gettext
from flask_login import current_user, login_required, logout_user, login_user from flask_login import current_user, login_required, logout_user, login_user
from flask_wtf import FlaskForm from flask_wtf import FlaskForm
from sqlalchemy import or_ from sqlalchemy import or_
@ -41,7 +42,7 @@ class LoginForm(FlaskForm):
def handle_login(form): def handle_login(form):
def show_safe_err(err): def show_safe_err(err):
if "@" in username: if "@" in username:
flash("Incorrect email or password", "danger") flash(gettext("Incorrect email or password"), "danger")
else: else:
flash(err, "danger") flash(err, "danger")
@ -49,13 +50,13 @@ def handle_login(form):
username = form.username.data.strip() username = form.username.data.strip()
user = User.query.filter(or_(User.username == username, User.email == username)).first() user = User.query.filter(or_(User.username == username, User.email == username)).first()
if user is None: if user is None:
return show_safe_err("User {} does not exist".format(username)) return show_safe_err(gettext(u"User %(username)s does not exist", username=username))
if not check_password_hash(user.password, form.password.data): if not check_password_hash(user.password, form.password.data):
return show_safe_err("Incorrect password. Did you set one?") return show_safe_err(gettext(u"Incorrect password. Did you set one?"))
if not user.is_active: if not user.is_active:
flash("You need to confirm the registration email", "danger") flash(gettext("You need to confirm the registration email"), "danger")
return return
addAuditLog(AuditSeverity.USER, user, "Logged in using password", addAuditLog(AuditSeverity.USER, user, "Logged in using password",
@ -63,7 +64,7 @@ def handle_login(form):
db.session.commit() db.session.commit()
if not login_user(user, remember=form.remember_me.data): if not login_user(user, remember=form.remember_me.data):
flash("Login failed", "danger") flash(gettext("Login failed"), "danger")
return return
return post_login(user, request.args.get("next")) return post_login(user, request.args.get("next"))
@ -110,7 +111,7 @@ class RegisterForm(FlaskForm):
def handle_register(form): def handle_register(form):
if form.question.data.strip().lower() != "19": if form.question.data.strip().lower() != "19":
flash("Incorrect captcha answer", "danger") flash(gettext("Incorrect captcha answer"), "danger")
return return
user_by_name = User.query.filter(or_( user_by_name = User.query.filter(or_(
@ -121,27 +122,27 @@ def handle_register(form):
User.github_username == form.username.data)).first() User.github_username == form.username.data)).first()
if user_by_name: if user_by_name:
if user_by_name.rank == UserRank.NOT_JOINED and user_by_name.forums_username: if user_by_name.rank == UserRank.NOT_JOINED and user_by_name.forums_username:
flash("An account already exists for that username but hasn't been claimed yet.", "danger") flash(gettext("An account already exists for that username but hasn't been claimed yet."), "danger")
return redirect(url_for("users.claim_forums", username=user_by_name.forums_username)) return redirect(url_for("users.claim_forums", username=user_by_name.forums_username))
else: else:
flash("That username/display name is already in use, please choose another.", "danger") flash(gettext("That username/display name is already in use, please choose another."), "danger")
return return
alias_by_name = PackageAlias.query.filter(or_( alias_by_name = PackageAlias.query.filter(or_(
PackageAlias.author==form.username.data, PackageAlias.author==form.username.data,
PackageAlias.author==form.display_name.data)).first() PackageAlias.author==form.display_name.data)).first()
if alias_by_name: if alias_by_name:
flash("That username/display name is already in use, please choose another.", "danger") flash(gettext("That username/display name is already in use, please choose another."), "danger")
return return
user_by_email = User.query.filter_by(email=form.email.data).first() user_by_email = User.query.filter_by(email=form.email.data).first()
if user_by_email: if user_by_email:
send_anon_email.delay(form.email.data, "Email already in use", send_anon_email.delay(form.email.data, "Email already in use",
"We were unable to create the account as the email is already in use by {}. Try a different email address.".format( gettext("We were unable to create the account as the email is already in use by %(display_name)s. Try a different email address.",
user_by_email.display_name)) display_name=user_by_email.display_name))
return redirect(url_for("flatpage", path="email_sent")) return redirect(url_for("flatpage", path="email_sent"))
elif EmailSubscription.query.filter_by(email=form.email.data, blacklisted=True).count() > 0: elif EmailSubscription.query.filter_by(email=form.email.data, blacklisted=True).count() > 0:
flash("That email address has been unsubscribed/blacklisted, and cannot be used", "danger") flash(gettext("That email address has been unsubscribed/blacklisted, and cannot be used"), "danger")
return return
user = User(form.username.data, False, form.email.data, make_flask_login_password(form.password.data)) user = User(form.username.data, False, form.email.data, make_flask_login_password(form.password.data))
@ -245,7 +246,7 @@ def handle_set_password(form):
one = form.password.data one = form.password.data
two = form.password2.data two = form.password2.data
if one != two: if one != two:
flash("Passwords do not much", "danger") flash(gettext("Passwords do not much"), "danger")
return return
addAuditLog(AuditSeverity.USER, current_user, "Changed their password", url_for("users.profile", username=current_user.username)) addAuditLog(AuditSeverity.USER, current_user, "Changed their password", url_for("users.profile", username=current_user.username))
@ -256,14 +257,14 @@ def handle_set_password(form):
newEmail = nonEmptyOrNone(form.email.data) newEmail = nonEmptyOrNone(form.email.data)
if newEmail and newEmail != current_user.email: if newEmail and newEmail != current_user.email:
if EmailSubscription.query.filter_by(email=form.email.data, blacklisted=True).count() > 0: if EmailSubscription.query.filter_by(email=form.email.data, blacklisted=True).count() > 0:
flash("That email address has been unsubscribed/blacklisted, and cannot be used", "danger") flash(gettext(u"That email address has been unsubscribed/blacklisted, and cannot be used"), "danger")
return return
user_by_email = User.query.filter_by(email=form.email.data).first() user_by_email = User.query.filter_by(email=form.email.data).first()
if user_by_email: if user_by_email:
send_anon_email.delay(form.email.data, "Email already in use", send_anon_email.delay(form.email.data, "Email already in use",
"We were unable to create the account as the email is already in use by {}. Try a different email address.".format( gettext(u"We were unable to create the account as the email is already in use by %(display_name)s. Try a different email address.",
user_by_email.display_name)) display_name=user_by_email.display_name))
else: else:
token = randomString(32) token = randomString(32)
@ -276,11 +277,11 @@ def handle_set_password(form):
send_verify_email.delay(form.email.data, token) send_verify_email.delay(form.email.data, token)
flash("Your password has been changed successfully.", "success") flash(gettext("Your password has been changed successfully."), "success")
return redirect(url_for("flatpage", path="email_sent")) return redirect(url_for("flatpage", path="email_sent"))
db.session.commit() db.session.commit()
flash("Your password has been changed successfully.", "success") flash(gettext("Your password has been changed successfully."), "success")
return redirect(url_for("homepage.home")) return redirect(url_for("homepage.home"))
@ -295,7 +296,7 @@ def change_password():
if ret: if ret:
return ret return ret
else: else:
flash("Old password is incorrect", "danger") flash(gettext("Old password is incorrect"), "danger")
return render_template("users/change_set_password.html", form=form, return render_template("users/change_set_password.html", form=form,
suggested_password=genphrase(entropy=52, wordset="bip39")) suggested_password=genphrase(entropy=52, wordset="bip39"))
@ -325,13 +326,13 @@ def verify_email():
token = request.args.get("token") token = request.args.get("token")
ver: UserEmailVerification = UserEmailVerification.query.filter_by(token=token).first() ver: UserEmailVerification = UserEmailVerification.query.filter_by(token=token).first()
if ver is None: if ver is None:
flash("Unknown verification token!", "danger") flash(gettext("Unknown verification token!"), "danger")
return redirect(url_for("homepage.home")) return redirect(url_for("homepage.home"))
delta = (datetime.datetime.now() - ver.created_at) delta = (datetime.datetime.now() - ver.created_at)
delta: datetime.timedelta delta: datetime.timedelta
if delta.total_seconds() > 12*60*60: if delta.total_seconds() > 12*60*60:
flash("Token has expired", "danger") flash(gettext("Token has expired"), "danger")
db.session.delete(ver) db.session.delete(ver)
db.session.commit() db.session.commit()
return redirect(url_for("homepage.home")) return redirect(url_for("homepage.home"))
@ -345,15 +346,15 @@ def verify_email():
if ver.email and user.email != ver.email: if ver.email and user.email != ver.email:
if User.query.filter_by(email=ver.email).count() > 0: if User.query.filter_by(email=ver.email).count() > 0:
flash("Another user is already using that email", "danger") flash(gettext("Another user is already using that email"), "danger")
return redirect(url_for("homepage.home")) return redirect(url_for("homepage.home"))
flash("Confirmed email change", "success") flash(gettext("Confirmed email change"), "success")
if user.email: if user.email:
send_user_email.delay(user.email, send_user_email.delay(user.email,
"Email address changed", gettext("Email address changed"),
"Your email address has changed. If you didn't request this, please contact an administrator.") gettext("Your email address has changed. If you didn't request this, please contact an administrator."))
user.is_active = True user.is_active = True
user.email = ver.email user.email = ver.email
@ -371,7 +372,7 @@ def verify_email():
if current_user.is_authenticated: if current_user.is_authenticated:
return redirect(url_for("users.profile", username=current_user.username)) return redirect(url_for("users.profile", username=current_user.username))
elif was_activating: elif was_activating:
flash("You may now log in", "success") flash(gettext("You may now log in"), "success")
return redirect(url_for("users.login")) return redirect(url_for("users.login"))
else: else:
return redirect(url_for("homepage.home")) return redirect(url_for("homepage.home"))
@ -410,7 +411,7 @@ def unsubscribe_manage(sub: EmailSubscription):
sub.blacklisted = True sub.blacklisted = True
db.session.commit() db.session.commit()
flash("That email is now blacklisted. Please contact an admin if you wish to undo this.", "success") flash(gettext("That email is now blacklisted. Please contact an admin if you wish to undo this."), "success")
return redirect(url_for("homepage.home")) return redirect(url_for("homepage.home"))
return render_template("users/unsubscribe.html", user=user) return render_template("users/unsubscribe.html", user=user)

View File

@ -13,6 +13,7 @@
# #
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
from flask_babel import gettext
from . import bp from . import bp
from flask import redirect, render_template, session, request, flash, url_for from flask import redirect, render_template, session, request, flash, url_for
@ -42,16 +43,16 @@ def claim_forums():
method = request.args.get("method") method = request.args.get("method")
if not check_username(username): if not check_username(username):
flash("Invalid username - must only contain A-Za-z0-9._. Consider contacting an admin", "danger") flash(gettext("Invalid username - must only contain A-Za-z0-9._. Consider contacting an admin"), "danger")
return redirect(url_for("users.claim_forums")) return redirect(url_for("users.claim_forums"))
user = User.query.filter_by(forums_username=username).first() user = User.query.filter_by(forums_username=username).first()
if user and user.rank.atLeast(UserRank.NEW_MEMBER): if user and user.rank.atLeast(UserRank.NEW_MEMBER):
flash("User has already been claimed", "danger") flash(gettext("User has already been claimed"), "danger")
return redirect(url_for("users.claim_forums")) return redirect(url_for("users.claim_forums"))
elif method == "github": elif method == "github":
if user is None or user.github_username is None: if user is None or user.github_username is None:
flash("Unable to get GitHub username for user", "danger") flash(gettext("Unable to get GitHub username for user"), "danger")
return redirect(url_for("users.claim_forums", username=username)) return redirect(url_for("users.claim_forums", username=username))
else: else:
return redirect(url_for("github.start")) return redirect(url_for("github.start"))
@ -67,14 +68,14 @@ def claim_forums():
username = request.form.get("username") username = request.form.get("username")
if not check_username(username): if not check_username(username):
flash("Invalid username - must only contain A-Za-z0-9._. Consider contacting an admin", "danger") flash(gettext("Invalid username - must only contain A-Za-z0-9._. Consider contacting an admin"), "danger")
elif ctype == "github": elif ctype == "github":
task = checkForumAccount.delay(username) task = checkForumAccount.delay(username)
return redirect(url_for("tasks.check", id=task.id, r=url_for("users.claim_forums", username=username, method="github"))) return redirect(url_for("tasks.check", id=task.id, r=url_for("users.claim_forums", username=username, method="github")))
elif ctype == "forum": elif ctype == "forum":
user = User.query.filter_by(forums_username=username).first() user = User.query.filter_by(forums_username=username).first()
if user is not None and user.rank.atLeast(UserRank.NEW_MEMBER): if user is not None and user.rank.atLeast(UserRank.NEW_MEMBER):
flash("That user has already been claimed!", "danger") flash(gettext("That user has already been claimed!"), "danger")
return redirect(url_for("users.claim_forums")) return redirect(url_for("users.claim_forums"))
# Get signature # Get signature
@ -88,11 +89,11 @@ def claim_forums():
else: else:
message = str(e) message = str(e)
flash("Error whilst attempting to access forums: " + message, "danger") flash(gettext(u"Error whilst attempting to access forums: %(message)s", message=message), "danger")
return redirect(url_for("users.claim_forums", username=username)) return redirect(url_for("users.claim_forums", username=username))
if profile is None: if profile is None:
flash("Unable to get forum signature - does the user exist?", "danger") flash(gettext("Unable to get forum signature - does the user exist?"), "danger")
return redirect(url_for("users.claim_forums", username=username)) return redirect(url_for("users.claim_forums", username=username))
# Look for key # Look for key
@ -107,15 +108,15 @@ def claim_forums():
ret = login_user_set_active(user, remember=True) ret = login_user_set_active(user, remember=True)
if ret is None: if ret is None:
flash("Unable to login as user", "danger") flash(gettext("Unable to login as user"), "danger")
return redirect(url_for("users.claim_forums", username=username)) return redirect(url_for("users.claim_forums", username=username))
return ret return ret
else: else:
flash("Could not find the key in your signature!", "danger") flash(gettext("Could not find the key in your signature!"), "danger")
return redirect(url_for("users.claim_forums", username=username)) return redirect(url_for("users.claim_forums", username=username))
else: else:
flash("Unknown claim type", "danger") flash(gettext("Unknown claim type"), "danger")
return render_template("users/claim_forums.html", username=username, key="cdb_" + token) return render_template("users/claim_forums.html", username=username, key="cdb_" + token)

View File

@ -1,4 +1,5 @@
from flask import * from flask import *
from flask_babel import gettext
from flask_login import current_user, login_required, logout_user from flask_login import current_user, login_required, logout_user
from flask_wtf import FlaskForm from flask_wtf import FlaskForm
from sqlalchemy import or_ from sqlalchemy import or_
@ -53,13 +54,13 @@ def handle_profile_edit(form, user, username):
if User.query.filter(User.id != user.id, if User.query.filter(User.id != user.id,
or_(User.username == form.display_name.data, or_(User.username == form.display_name.data,
User.display_name.ilike(form.display_name.data))).count() > 0: User.display_name.ilike(form.display_name.data))).count() > 0:
flash("A user already has that name", "danger") flash(gettext("A user already has that name"), "danger")
return None return None
alias_by_name = PackageAlias.query.filter(or_( alias_by_name = PackageAlias.query.filter(or_(
PackageAlias.author == form.display_name.data)).first() PackageAlias.author == form.display_name.data)).first()
if alias_by_name: if alias_by_name:
flash("A user already has that name", "danger") flash(gettext("A user already has that name"), "danger")
return return
user.display_name = form.display_name.data user.display_name = form.display_name.data
@ -86,7 +87,7 @@ def profile_edit(username):
abort(404) abort(404)
if not user.can_see_edit_profile(current_user): if not user.can_see_edit_profile(current_user):
flash("Permission denied", "danger") flash(gettext("Permission denied"), "danger")
return redirect(url_for("users.profile", username=username)) return redirect(url_for("users.profile", username=username))
form = UserProfileForm(obj=user) form = UserProfileForm(obj=user)
@ -211,7 +212,7 @@ def account(username):
abort(404) abort(404)
if not user.can_see_edit_profile(current_user): if not user.can_see_edit_profile(current_user):
flash("Permission denied", "danger") flash(gettext("Permission denied"), "danger")
return redirect(url_for("users.profile", username=username)) return redirect(url_for("users.profile", username=username))
can_edit_account_settings = user.checkPerm(current_user, Permission.CHANGE_USERNAMES) or \ can_edit_account_settings = user.checkPerm(current_user, Permission.CHANGE_USERNAMES) or \
@ -245,7 +246,7 @@ def account(username):
addAuditLog(AuditSeverity.MODERATION, current_user, msg, addAuditLog(AuditSeverity.MODERATION, current_user, msg,
url_for("users.profile", username=username)) url_for("users.profile", username=username))
else: else:
flash("Can't promote a user to a rank higher than yourself!", "danger") flash(gettext("Can't promote a user to a rank higher than yourself!"), "danger")
db.session.commit() db.session.commit()
@ -262,7 +263,7 @@ def delete(username):
abort(404) abort(404)
if user.rank.atLeast(UserRank.MODERATOR): if user.rank.atLeast(UserRank.MODERATOR):
flash("Users with moderator rank or above cannot be deleted", "danger") flash(gettext("Users with moderator rank or above cannot be deleted"), "danger")
return redirect(url_for("users.account", username=username)) return redirect(url_for("users.account", username=username))
if request.method == "GET": if request.method == "GET":

View File

@ -17,6 +17,7 @@
from functools import wraps from functools import wraps
from flask_babel import gettext
from flask_login import login_user, current_user from flask_login import login_user, current_user
from passlib.handlers.bcrypt import bcrypt from passlib.handlers.bcrypt import bcrypt
from flask import redirect, url_for, abort, flash from flask import redirect, url_for, abort, flash
@ -46,11 +47,11 @@ def post_login(user: User, next_url):
notif_count = len(user.notifications) notif_count = len(user.notifications)
if notif_count > 0: if notif_count > 0:
if notif_count >= 10: if notif_count >= 10:
flash("You have a lot of notifications, you should either read or clear them", "info") flash(gettext("You have a lot of notifications, you should either read or clear them"), "info")
return redirect(url_for("notifications.list_all")) return redirect(url_for("notifications.list_all"))
if user.notification_preferences is None: if user.notification_preferences is None:
flash("Please consider enabling email notifications, you can customise how much is sent", "info") flash(gettext("Please consider enabling email notifications, you can customise how much is sent"), "info")
return redirect(url_for("users.email_notifications", username=user.username)) return redirect(url_for("users.email_notifications", username=user.username))
return redirect(url_for("homepage.home")) return redirect(url_for("homepage.home"))