Skip to content

Commit

Permalink
Merge pull request #18 from kianby/feature-refactor-startup
Browse files Browse the repository at this point in the history
Feature refactor startup
  • Loading branch information
kianby committed Apr 12, 2024
2 parents 83aa8b1 + 53316c2 commit ac5345d
Show file tree
Hide file tree
Showing 12 changed files with 123 additions and 118 deletions.
28 changes: 14 additions & 14 deletions requirements-dev.lock
Expand Up @@ -10,7 +10,7 @@
altgraph==0.17.4
astroid==3.1.0
background==0.2.1
black==24.2.0
black==24.3.0
blinker==1.7.0
certifi==2024.2.2
charset-normalizer==3.3.2
Expand All @@ -20,34 +20,34 @@ coveralls==3.3.1
dill==0.3.8
docopt==0.6.2
exceptiongroup==1.2.0
flask==3.0.2
idna==3.6
flask==3.0.3
idna==3.7
iniconfig==2.0.0
isort==5.13.2
itsdangerous==2.1.2
jinja2==3.1.3
markdown==3.5.2
markdown==3.6
markupsafe==2.1.5
mccabe==0.7.0
mypy==1.8.0
mypy==1.9.0
mypy-extensions==1.0.0
packaging==23.2
packaging==24.0
pathspec==0.12.1
platformdirs==4.2.0
pluggy==1.4.0
pydal==20231114.3
pyinstaller==6.4.0
pyinstaller-hooks-contrib==2024.1
pyinstaller==6.5.0
pyinstaller-hooks-contrib==2024.3
pylint==3.1.0
pyrss2gen==1.1
pytest==8.0.2
pytest-cov==4.1.0
pytest==8.1.1
pytest-cov==5.0.0
requests==2.31.0
tomli==2.0.1
tomlkit==0.12.4
types-markdown==3.5.0.20240129
typing-extensions==4.10.0
types-markdown==3.6.0.20240316
typing-extensions==4.11.0
urllib3==2.2.1
werkzeug==3.0.1
werkzeug==3.0.2
# The following packages are considered to be unsafe in a requirements file:
setuptools==69.1.1
setuptools==69.3.0
10 changes: 5 additions & 5 deletions requirements.lock
Expand Up @@ -12,15 +12,15 @@ blinker==1.7.0
certifi==2024.2.2
charset-normalizer==3.3.2
click==8.1.7
flask==3.0.2
idna==3.6
flask==3.0.3
idna==3.7
itsdangerous==2.1.2
jinja2==3.1.3
markdown==3.5.2
markdown==3.6
markupsafe==2.1.5
pydal==20231114.3
pyrss2gen==1.1
requests==2.31.0
types-markdown==3.5.0.20240129
types-markdown==3.6.0.20240316
urllib3==2.2.1
werkzeug==3.0.1
werkzeug==3.0.2
7 changes: 3 additions & 4 deletions src/stacosys/interface/__init__.py
Expand Up @@ -7,7 +7,6 @@
from flask import Flask

from stacosys.db import dao
from stacosys.service import config, mailer
from stacosys.service.configuration import ConfigParameter

app = Flask(__name__)
Expand All @@ -20,7 +19,7 @@

@background.task
def submit_new_comment(comment):
site_url = config.get(ConfigParameter.SITE_URL)
site_url = app.config["CONFIG"].get(ConfigParameter.SITE_URL)
comment_list = (
f"Web admin interface: {site_url}/web/admin",
"",
Expand All @@ -35,9 +34,9 @@ def submit_new_comment(comment):
email_body = "\n".join(comment_list)

# send email to notify admin
site_name = config.get(ConfigParameter.SITE_NAME)
site_name = app.config["CONFIG"].get(ConfigParameter.SITE_NAME)
subject = f"STACOSYS {site_name}"
if mailer.send(subject, email_body):
if app.config["MAILER"].send(subject, email_body):
logger.debug("new comment processed")
# save notification datetime
dao.notify_comment(comment)
3 changes: 1 addition & 2 deletions src/stacosys/interface/form.py
Expand Up @@ -6,7 +6,6 @@

from stacosys.db import dao
from stacosys.interface import app, submit_new_comment
from stacosys.service import config
from stacosys.service.configuration import ConfigParameter

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -47,7 +46,7 @@ def new_form_comment():
# send notification e-mail asynchronously
submit_new_comment(comment)

return redirect(config.get(ConfigParameter.SITE_REDIRECT), code=302)
return redirect(app.config["CONFIG"].get(ConfigParameter.SITE_REDIRECT), code=302)


def check_form_data(posted_comment):
Expand Down
17 changes: 9 additions & 8 deletions src/stacosys/interface/web/admin.py
Expand Up @@ -8,7 +8,6 @@

from stacosys.db import dao
from stacosys.interface import app
from stacosys.service import config, rss
from stacosys.service.configuration import ConfigParameter

logger = logging.getLogger(__name__)
Expand All @@ -25,8 +24,8 @@ def index():
def is_login_ok(username, password):
hashed = hashlib.sha256(password.encode()).hexdigest().upper()
return (
config.get(ConfigParameter.WEB_USERNAME) == username
and config.get(ConfigParameter.WEB_PASSWORD) == hashed
app.config["CONFIG"].get(ConfigParameter.WEB_USERNAME) == username
and app.config["CONFIG"].get(ConfigParameter.WEB_PASSWORD) == hashed
)


Expand All @@ -42,7 +41,9 @@ def login():
flash("Identifiant ou mot de passe incorrect")
return redirect("/web/login")
# GET
return render_template("login_" + config.get(ConfigParameter.LANG) + ".html")
return render_template(
"login_" + app.config["CONFIG"].get(ConfigParameter.LANG) + ".html"
)


@app.route("/web/logout", methods=["GET"])
Expand All @@ -55,17 +56,17 @@ def logout():
def admin_homepage():
if not (
"user" in session
and session["user"] == 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")

comments = dao.find_not_published_comments()
return render_template(
"admin_" + config.get(ConfigParameter.LANG) + ".html",
"admin_" + app.config["CONFIG"].get(ConfigParameter.LANG) + ".html",
comments=comments,
baseurl=config.get(ConfigParameter.SITE_URL),
baseurl=app.config["CONFIG"].get(ConfigParameter.SITE_URL),
)


Expand All @@ -77,7 +78,7 @@ def admin_action():
flash("Commentaire introuvable")
elif request.form.get("action") == "APPROVE":
dao.publish_comment(comment)
rss.generate()
app.config["RSS"].generate()
# TODO localization
flash("Commentaire publié")
else:
Expand Down
89 changes: 50 additions & 39 deletions src/stacosys/run.py
Expand Up @@ -9,67 +9,74 @@
from stacosys.db import database
from stacosys.interface import api, app, form
from stacosys.interface.web import admin
from stacosys.service import config, mailer, rss
from stacosys.service.configuration import ConfigParameter
from stacosys.service.configuration import Config, ConfigParameter
from stacosys.service.mail import Mailer
from stacosys.service.rssfeed import Rss


# configure logging
def configure_logging(level):
root_logger = logging.getLogger()
root_logger.setLevel(level)
handler = logging.StreamHandler()
handler.setLevel(level)
formatter = logging.Formatter("[%(asctime)s] %(name)s %(levelname)s %(message)s")
handler.setFormatter(formatter)
root_logger.addHandler(handler)


def stacosys_server(config_pathname):
# configure logging
def configure_logging() -> logging.Logger:
logging.basicConfig(
level=logging.INFO, format="[%(asctime)s] %(name)s %(levelname)s %(message)s"
)
logger = logging.getLogger(__name__)
configure_logging(logging.INFO)
logging.getLogger("werkzeug").level = logging.WARNING
return logger


# check config file exists
def load_and_validate_config(config_pathname: str, logger: logging.Logger) -> Config:
if not os.path.isfile(config_pathname):
logger.error("Configuration file '%s' not found.", config_pathname)
sys.exit(1)
raise FileNotFoundError(f"Configuration file '{config_pathname}' not found.")

# load and check config
config = Config()
config.load(config_pathname)
is_config_ok, erreur_config = config.check()
if not is_config_ok:
logger.error("Configuration incorrecte '%s'", erreur_config)
sys.exit(1)
logger.info(config)
if not config.check():
raise ValueError(f"Invalid configuration '{config_pathname}'")
logger.info("Configuration loaded successfully.")
return config

# initialize database
database.configure(config.get(ConfigParameter.DB))

logger.info("Start Stacosys application")
def configure_and_validate_mailer(config, logger):
mailer = Mailer()
mailer.configure_smtp(
config.get(ConfigParameter.SMTP_HOST),
config.get_int(ConfigParameter.SMTP_PORT),
config.get(ConfigParameter.SMTP_LOGIN),
config.get(ConfigParameter.SMTP_PASSWORD),
)
mailer.configure_destination(config.get(ConfigParameter.SITE_ADMIN_EMAIL))
if not mailer.check():
logger.error("Email configuration not working")
sys.exit(1)
return mailer

# generate RSS

def configure_rss(config):
rss = Rss()
rss.configure(
config.get(ConfigParameter.RSS_FILE),
config.get(ConfigParameter.SITE_NAME),
config.get(ConfigParameter.SITE_PROTO),
config.get(ConfigParameter.SITE_URL),
)
rss.generate()
return rss

# configure mailer
mailer.configure_smtp(
config.get(ConfigParameter.SMTP_HOST),
config.get_int(ConfigParameter.SMTP_PORT),
config.get(ConfigParameter.SMTP_LOGIN),
config.get(ConfigParameter.SMTP_PASSWORD),
)
mailer.configure_destination(config.get(ConfigParameter.SITE_ADMIN_EMAIL))
mailer.check()

logger.info("start interfaces %s %s %s", api, form, admin)
def main(config_pathname):
logger = configure_logging()
config = load_and_validate_config(config_pathname, logger)
database.configure(config.get(ConfigParameter.DB))

# start Flask
logger.info("Start Stacosys application")
rss = configure_rss(config)
mailer = configure_and_validate_mailer(config, logger)

logger.info("start interfaces %s %s %s", api, form, admin)
app.config["CONFIG"] = config
app.config["MAILER"] = mailer
app.config["RSS"] = rss
app.run(
host=config.get(ConfigParameter.HTTP_HOST),
port=config.get_int(ConfigParameter.HTTP_PORT),
Expand All @@ -82,4 +89,8 @@ def stacosys_server(config_pathname):
parser = argparse.ArgumentParser()
parser.add_argument("config", help="config path name")
args = parser.parse_args()
stacosys_server(args.config)
try:
main(args.config)
except Exception as e:
logging.error(f"Failed to start application: {e}")
sys.exit(1)
10 changes: 0 additions & 10 deletions src/stacosys/service/__init__.py

This file was deleted.

0 comments on commit ac5345d

Please sign in to comment.