diff --git a/src/stacosys/i18n/messages.py b/src/stacosys/i18n/messages.py
new file mode 100644
index 0000000..d64cbac
--- /dev/null
+++ b/src/stacosys/i18n/messages.py
@@ -0,0 +1,17 @@
+import configparser
+import os
+
+
+class Messages:
+ def __init__(self):
+ self.property_dict = {}
+
+ def load_messages(self, lang):
+ config = configparser.ConfigParser()
+ config.read(os.path.join(os.path.dirname(__file__), 'messages_' + lang + '.properties'))
+
+ for key, value in config.items('messages'):
+ self.property_dict[key] = value
+
+ def get(self, key):
+ return self.property_dict.get(key)
diff --git a/src/stacosys/i18n/messages_en.properties b/src/stacosys/i18n/messages_en.properties
new file mode 100644
index 0000000..85d02a7
--- /dev/null
+++ b/src/stacosys/i18n/messages_en.properties
@@ -0,0 +1,6 @@
+[messages]
+login.failure.username=Username or password incorrect
+logout.flash=You have been logged out.
+admin.comment.notfound=Comment not found.
+admin.comment.approved=Comment published.
+admin.comment.deleted=Comment deleted.
\ No newline at end of file
diff --git a/src/stacosys/i18n/messages_fr.properties b/src/stacosys/i18n/messages_fr.properties
new file mode 100644
index 0000000..9137863
--- /dev/null
+++ b/src/stacosys/i18n/messages_fr.properties
@@ -0,0 +1,6 @@
+[messages]
+login.failure.username=Identifiant ou mot de passe incorrect
+logout.flash=Vous avez été déconnecté.
+admin.comment.notfound=Commentaire introuvable
+admin.comment.approved=Commentaire publié
+admin.comment.deleted=Commentaire supprimé
\ No newline at end of file
diff --git a/src/stacosys/interface/templates/admin_en.html b/src/stacosys/interface/templates/admin_en.html
new file mode 100644
index 0000000..59c8f19
--- /dev/null
+++ b/src/stacosys/interface/templates/admin_en.html
@@ -0,0 +1,64 @@
+
+
+
+
+
+Stacosys Comment Moderation
+
+
+
+
+ Comment Moderation
+
+
+
+ {% with messages = get_flashed_messages() %}
+ {% if messages %}
+
+ {% for message in messages %}
+ {{ message }}
+ {% endfor %}
+
+ {% endif %}
+ {% endwith %}
+
+
+
+ Date |
+ Author |
+ Comment |
+ Article |
+ Actions |
+
+
+
+ {% for comment in comments %}
+
+ {{ comment.created }} |
+ {{ comment.author_name }} |
+ {{ comment.content }} |
+ {{ comment.url }} |
+
+
+
+ |
+
+ {% endfor %}
+
+
+
+
+
+
diff --git a/src/stacosys/interface/templates/login_en.html b/src/stacosys/interface/templates/login_en.html
new file mode 100644
index 0000000..6d81754
--- /dev/null
+++ b/src/stacosys/interface/templates/login_en.html
@@ -0,0 +1,42 @@
+
+
+
+
+
+Stacosys
+
+
+
+
+
+ Comment Moderation Login
+
+
+ {% with messages = get_flashed_messages() %}
+ {% if messages %}
+
+ {% for message in messages %}
+ {{ message }}
+ {% endfor %}
+
+ {% endif %}
+ {% endwith %}
+
+
+
+
+
diff --git a/src/stacosys/interface/web/admin.py b/src/stacosys/interface/web/admin.py
index 64aa3da..9b8c0ef 100644
--- a/src/stacosys/interface/web/admin.py
+++ b/src/stacosys/interface/web/admin.py
@@ -37,8 +37,7 @@ def login():
if is_login_ok(username, password):
session["user"] = username
return redirect("/web/admin")
- # TODO localization
- flash("Identifiant ou mot de passe incorrect")
+ flash(app.config["MESSAGES"].get("login.failure.username"))
return redirect("/web/login")
# GET
return render_template(
@@ -49,6 +48,7 @@ def login():
@app.route("/web/logout", methods=["GET"])
def logout():
session.pop("user")
+ flash(app.config["MESSAGES"].get("logout.flash"))
return redirect("/web/admin")
@@ -58,8 +58,6 @@ def admin_homepage():
"user" in session
and session["user"] == app.config["CONFIG"].get(ConfigParameter.WEB_USERNAME)
):
- # TODO localization
- flash("Vous avez été déconnecté.")
return redirect("/web/login")
comments = dao.find_not_published_comments()
@@ -74,15 +72,12 @@ def admin_homepage():
def admin_action():
comment = dao.find_comment_by_id(request.form.get("comment"))
if comment is None:
- # TODO localization
- flash("Commentaire introuvable")
+ flash(app.config["MESSAGES"].get("admin.comment.notfound"))
elif request.form.get("action") == "APPROVE":
dao.publish_comment(comment)
app.config["RSS"].generate()
- # TODO localization
- flash("Commentaire publié")
+ flash(app.config["MESSAGES"].get("admin.comment.approved"))
else:
dao.delete_comment(comment)
- # TODO localization
- flash("Commentaire supprimé")
+ flash(app.config["MESSAGES"].get("admin.comment.deleted"))
return redirect("/web/admin")
diff --git a/src/stacosys/run.py b/src/stacosys/run.py
index 5634764..255c424 100644
--- a/src/stacosys/run.py
+++ b/src/stacosys/run.py
@@ -7,6 +7,7 @@ import os
import sys
from stacosys.db import database
+from stacosys.i18n.messages import Messages
from stacosys.interface import api, app, form
from stacosys.interface.web import admin
from stacosys.service.configuration import Config, ConfigParameter
@@ -64,6 +65,12 @@ def configure_rss(config):
return rss
+def configure_localization(config):
+ messages = Messages()
+ messages.load_messages(config.get(ConfigParameter.LANG))
+ return messages
+
+
def main(config_pathname):
logger = configure_logging()
config = load_and_validate_config(config_pathname, logger)
@@ -72,11 +79,13 @@ def main(config_pathname):
logger.info("Start Stacosys application")
rss = configure_rss(config)
mailer = configure_and_validate_mailer(config, logger)
+ messages = configure_localization(config)
logger.info("start interfaces %s %s %s", api, form, admin)
app.config["CONFIG"] = config
app.config["MAILER"] = mailer
app.config["RSS"] = rss
+ app.config["MESSAGES"] = messages
app.run(
host=config.get(ConfigParameter.HTTP_HOST),
port=config.get_int(ConfigParameter.HTTP_PORT),
diff --git a/src/stacosys/service/mail.py b/src/stacosys/service/mail.py
index 4e52228..6aa9470 100644
--- a/src/stacosys/service/mail.py
+++ b/src/stacosys/service/mail.py
@@ -38,21 +38,22 @@ class Mailer:
def send(self, subject: str, message: str) -> bool:
sender = self._smtp_login
- receivers = [self._site_admin_email]
-
- msg = MIMEText(message)
- msg["Subject"] = subject
- msg["To"] = self._site_admin_email
- msg["From"] = sender
try:
+ msg = MIMEText(message)
+ msg["Subject"] = subject
+ msg["From"] = sender
+ msg["To"] = self._site_admin_email
+
with SMTP_SSL(self._smtp_host, self._smtp_port) as server:
- server.login(self._smtp_login, self._smtp_password)
- server.send_message(msg, sender, receivers)
+ try:
+ server.login(self._smtp_login, self._smtp_password)
+ except SMTPAuthenticationError:
+ logger.exception("Invalid credentials")
+ return False
+
+ server.send_message(msg)
return True
- except SMTPAuthenticationError:
- logger.exception("Invalid credentials")
- return False
- except Exception as e:
- logger.exception(f"Error sending email: {e}")
- return False
+ except Exception:
+ logger.error("Error sending email", exc_info=True)
+ return False
diff --git a/src/stacosys/service/rssfeed.py b/src/stacosys/service/rssfeed.py
index 069448f..9c9ebe0 100644
--- a/src/stacosys/service/rssfeed.py
+++ b/src/stacosys/service/rssfeed.py
@@ -52,5 +52,5 @@ class Rss:
lastBuildDate=datetime.now(),
items=items,
)
- # pylint: disable=consider-using-with
- rss.write_xml(open(self._rss_file, "w", encoding="utf-8"), encoding="utf-8")
+ with open(self._rss_file, "w", encoding="utf-8") as outfile:
+ rss.write_xml(outfile, encoding="utf-8")