Merge pull request #19 from kianby/feature-improvements

Feature improvements
pull/20/head
Yax 5 months ago committed by GitHub
commit 8d663c7ee7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -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)

@ -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.

@ -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é

@ -0,0 +1,64 @@
<!doctype html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Stacosys Comment Moderation</title>
<link rel="stylesheet" href="https://cdn.simplecss.org/simple.min.css">
</head>
<body>
<header>
<h2>Comment Moderation</h2>
<nav>
<a href="/web/logout">Log out</a>
</nav>
</header>
<main>
{% with messages = get_flashed_messages() %}
{% if messages %}
<blockquote>
{% for message in messages %}
<p>{{ message }}</p>
{% endfor %}
</blockquote>
{% endif %}
{% endwith %}
<table>
<thead>
<tr>
<th>Date</th>
<th>Author</th>
<th>Comment</th>
<th>Article</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for comment in comments %}
<tr>
<td>{{ comment.created }}</td>
<td>{{ comment.author_name }}</td>
<td>{{ comment.content }}</td>
<td><a href="{{ baseurl + comment.url }}">{{ comment.url }}</a></td>
<td>
<form action="/web/admin" method="post">
<input type="hidden" name="comment" value="{{comment.id}}">
<input type="hidden" name="action" value="APPROVE">
<button type="submit">Approve</button>
</form>
<form action="/web/admin" method="post">
<input type="hidden" name="comment" value="{{comment.id}}">
<input type="hidden" name="action" value="REJECT">
<button type="submit">Reject</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</main>
<footer>
<p>This page was designed by Yax with <a href="https://simplecss.org">Simple.css</a>.</p>
</footer>
</body>
</html>

@ -0,0 +1,42 @@
<!doctype html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Stacosys</title>
<link rel="stylesheet" href="https://cdn.simplecss.org/simple.min.css">
<style>
form {
width: 350px;
margin: 0 auto;
text-align: center;
}
</style>
</head>
<body>
<header>
<h2>Comment Moderation Login</h2>
</header>
<main>
{% with messages = get_flashed_messages() %}
{% if messages %}
<blockquote>
{% for message in messages %}
<p>{{ message }}</p>
{% endfor %}
</blockquote>
{% endif %}
{% endwith %}
<form action="/web/login" method="POST">
<p><label>Username:</label></p>
<p><input type="text" name="username" /></p>
<p><label>Password:</label></p>
<p><input type="password" name="password" /></p>
<input type="submit" value="Log in" />
</form>
</main>
<footer>
<p>This page was designed with <a href="https://simplecss.org">Simple.css</a>.</p>
</footer>
</body>
</html>

@ -37,8 +37,7 @@ def login():
if is_login_ok(username, password): if is_login_ok(username, password):
session["user"] = username session["user"] = username
return redirect("/web/admin") return redirect("/web/admin")
# TODO localization flash(app.config["MESSAGES"].get("login.failure.username"))
flash("Identifiant ou mot de passe incorrect")
return redirect("/web/login") return redirect("/web/login")
# GET # GET
return render_template( return render_template(
@ -49,6 +48,7 @@ def login():
@app.route("/web/logout", methods=["GET"]) @app.route("/web/logout", methods=["GET"])
def logout(): def logout():
session.pop("user") session.pop("user")
flash(app.config["MESSAGES"].get("logout.flash"))
return redirect("/web/admin") return redirect("/web/admin")
@ -58,8 +58,6 @@ def admin_homepage():
"user" in session "user" in session
and session["user"] == app.config["CONFIG"].get(ConfigParameter.WEB_USERNAME) and session["user"] == app.config["CONFIG"].get(ConfigParameter.WEB_USERNAME)
): ):
# TODO localization
flash("Vous avez été déconnecté.")
return redirect("/web/login") return redirect("/web/login")
comments = dao.find_not_published_comments() comments = dao.find_not_published_comments()
@ -74,15 +72,12 @@ def admin_homepage():
def admin_action(): def admin_action():
comment = dao.find_comment_by_id(request.form.get("comment")) comment = dao.find_comment_by_id(request.form.get("comment"))
if comment is None: if comment is None:
# TODO localization flash(app.config["MESSAGES"].get("admin.comment.notfound"))
flash("Commentaire introuvable")
elif request.form.get("action") == "APPROVE": elif request.form.get("action") == "APPROVE":
dao.publish_comment(comment) dao.publish_comment(comment)
app.config["RSS"].generate() app.config["RSS"].generate()
# TODO localization flash(app.config["MESSAGES"].get("admin.comment.approved"))
flash("Commentaire publié")
else: else:
dao.delete_comment(comment) dao.delete_comment(comment)
# TODO localization flash(app.config["MESSAGES"].get("admin.comment.deleted"))
flash("Commentaire supprimé")
return redirect("/web/admin") return redirect("/web/admin")

@ -7,6 +7,7 @@ import os
import sys import sys
from stacosys.db import database from stacosys.db import database
from stacosys.i18n.messages import Messages
from stacosys.interface import api, app, form from stacosys.interface import api, app, form
from stacosys.interface.web import admin from stacosys.interface.web import admin
from stacosys.service.configuration import Config, ConfigParameter from stacosys.service.configuration import Config, ConfigParameter
@ -64,6 +65,12 @@ def configure_rss(config):
return rss return rss
def configure_localization(config):
messages = Messages()
messages.load_messages(config.get(ConfigParameter.LANG))
return messages
def main(config_pathname): def main(config_pathname):
logger = configure_logging() logger = configure_logging()
config = load_and_validate_config(config_pathname, logger) config = load_and_validate_config(config_pathname, logger)
@ -72,11 +79,13 @@ def main(config_pathname):
logger.info("Start Stacosys application") logger.info("Start Stacosys application")
rss = configure_rss(config) rss = configure_rss(config)
mailer = configure_and_validate_mailer(config, logger) mailer = configure_and_validate_mailer(config, logger)
messages = configure_localization(config)
logger.info("start interfaces %s %s %s", api, form, admin) logger.info("start interfaces %s %s %s", api, form, admin)
app.config["CONFIG"] = config app.config["CONFIG"] = config
app.config["MAILER"] = mailer app.config["MAILER"] = mailer
app.config["RSS"] = rss app.config["RSS"] = rss
app.config["MESSAGES"] = messages
app.run( app.run(
host=config.get(ConfigParameter.HTTP_HOST), host=config.get(ConfigParameter.HTTP_HOST),
port=config.get_int(ConfigParameter.HTTP_PORT), port=config.get_int(ConfigParameter.HTTP_PORT),

@ -38,21 +38,22 @@ class Mailer:
def send(self, subject: str, message: str) -> bool: def send(self, subject: str, message: str) -> bool:
sender = self._smtp_login 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: 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: with SMTP_SSL(self._smtp_host, self._smtp_port) as server:
server.login(self._smtp_login, self._smtp_password) try:
server.send_message(msg, sender, receivers) server.login(self._smtp_login, self._smtp_password)
except SMTPAuthenticationError:
logger.exception("Invalid credentials")
return False
server.send_message(msg)
return True return True
except SMTPAuthenticationError: except Exception:
logger.exception("Invalid credentials") logger.error("Error sending email", exc_info=True)
return False return False
except Exception as e:
logger.exception(f"Error sending email: {e}")
return False

@ -52,5 +52,5 @@ class Rss:
lastBuildDate=datetime.now(), lastBuildDate=datetime.now(),
items=items, items=items,
) )
# pylint: disable=consider-using-with with open(self._rss_file, "w", encoding="utf-8") as outfile:
rss.write_xml(open(self._rss_file, "w", encoding="utf-8"), encoding="utf-8") rss.write_xml(outfile, encoding="utf-8")

Loading…
Cancel
Save