Show the version in a footer for logged-in users
The version is read once at startup from the VERSION file, which is now also copied into the Docker image. The footer is right-aligned below the content block and only shown to logged-in users, so anonymous visitors do not learn the exact version. The startup log now has "Max starting." at the beginning of main() and "Max initialized, version X." at the end, so a failed startup is visible by the missing second line. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
2b1160862a
commit
f46a346078
5 files changed
+31
-1
No files matched your search
@@ -32,6 +32,7 @@ ENV MAX_PRODUCTION=1
|
|||||||
# Owned by root, so the app cannot modify its own code
|
# Owned by root, so the app cannot modify its own code
|
||||||
COPY max/ ./max
|
COPY max/ ./max
|
||||||
COPY scripts/prod/ .
|
COPY scripts/prod/ .
|
||||||
|
COPY VERSION .
|
||||||
# Precompile, since the app cannot write __pycache__ at runtime
|
# Precompile, since the app cannot write __pycache__ at runtime
|
||||||
RUN python -m compileall -q max
|
RUN python -m compileall -q max
|
||||||
|
|
||||||
|
|||||||
+4
-1
@@ -19,6 +19,7 @@ from .routes import init_routes
|
|||||||
from .security_headers import init_security_headers
|
from .security_headers import init_security_headers
|
||||||
from .sessions import SessionInterface
|
from .sessions import SessionInterface
|
||||||
from .translations import TranslationHandler
|
from .translations import TranslationHandler
|
||||||
|
from .version import init_version
|
||||||
|
|
||||||
|
|
||||||
class Rule(WerkzeugRule):
|
class Rule(WerkzeugRule):
|
||||||
@@ -29,7 +30,7 @@ class Rule(WerkzeugRule):
|
|||||||
def main():
|
def main():
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
init_logging(app)
|
init_logging(app)
|
||||||
app.logger.info("Max started.")
|
app.logger.info("Max starting.")
|
||||||
if app.debug and os.environ.get("MAX_PRODUCTION") == "1":
|
if app.debug and os.environ.get("MAX_PRODUCTION") == "1":
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
"Debug mode is not allowed in production (MAX_PRODUCTION=1), unset FLASK_DEBUG"
|
"Debug mode is not allowed in production (MAX_PRODUCTION=1), unset FLASK_DEBUG"
|
||||||
@@ -39,6 +40,7 @@ def main():
|
|||||||
else:
|
else:
|
||||||
app.logger.info("App is in production mode")
|
app.logger.info("App is in production mode")
|
||||||
TranslationHandler.init(app)
|
TranslationHandler.init(app)
|
||||||
|
init_version(app)
|
||||||
app.jinja_env.trim_blocks = True
|
app.jinja_env.trim_blocks = True
|
||||||
app.jinja_env.lstrip_blocks = True
|
app.jinja_env.lstrip_blocks = True
|
||||||
app.url_rule_class = Rule
|
app.url_rule_class = Rule
|
||||||
@@ -70,6 +72,7 @@ def main():
|
|||||||
init_auth(app)
|
init_auth(app)
|
||||||
init_routes(app)
|
init_routes(app)
|
||||||
init_security_headers(app)
|
init_security_headers(app)
|
||||||
|
app.logger.info("Max initialized, version %s.", app.config["VERSION"])
|
||||||
return app
|
return app
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -108,6 +108,13 @@ form {
|
|||||||
background-color: #FFFFFF;
|
background-color: #FFFFFF;
|
||||||
border: 1px solid #CCCCCC;
|
border: 1px solid #CCCCCC;
|
||||||
}
|
}
|
||||||
|
footer {
|
||||||
|
width: calc(60% + 32px);
|
||||||
|
margin: -14px auto 20px auto;
|
||||||
|
text-align: right;
|
||||||
|
font-size: 0.8em;
|
||||||
|
color: #888888;
|
||||||
|
}
|
||||||
|
|
||||||
.top-row-button {
|
.top-row-button {
|
||||||
margin: 1.1em 0;
|
margin: 1.1em 0;
|
||||||
@@ -210,6 +217,11 @@ form {
|
|||||||
width: calc(100% - 72px);
|
width: calc(100% - 72px);
|
||||||
margin: 60px 20px 20px 20px;
|
margin: 60px 20px 20px 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
width: calc(100% - 40px);
|
||||||
|
margin: -14px 20px 20px 20px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 900px) {
|
@media (max-width: 900px) {
|
||||||
|
|||||||
@@ -62,6 +62,11 @@
|
|||||||
<div class="content">
|
<div class="content">
|
||||||
{% block content %}{% endblock %}
|
{% block content %}{% endblock %}
|
||||||
</div>
|
</div>
|
||||||
|
{% if session['user_id'] %}
|
||||||
|
<footer>
|
||||||
|
Version {{ version }}
|
||||||
|
</footer>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
VERSION_FILE = Path(__file__).resolve().parent.parent / "VERSION"
|
||||||
|
|
||||||
|
|
||||||
|
def init_version(app):
|
||||||
|
version = VERSION_FILE.read_text(encoding="utf-8").strip()
|
||||||
|
app.config["VERSION"] = version
|
||||||
|
app.context_processor(lambda: dict(version=version))
|
||||||
Reference in new issue
Block a user