-
Notifications
You must be signed in to change notification settings - Fork 6
Documentation: Add German Versions. #94
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
4b7a37c to
e882fba
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds German language support for user manuals by implementing localized documentation serving based on URL language parameters.
- Extends manual generation to include German translations (
user-manual_de.htmlandmobile-manual_de.html) - Implements language-aware routing in server endpoints to serve localized manuals
- Updates
.gitignoreto exclude generated German manual files
Reviewed Changes
Copilot reviewed 2 out of 3 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| src/web/subsurfacesync.py | Extended build and copy operations to include German manual files |
| src/web/server.py | Added language detection logic to serve localized manuals based on lang query parameter |
| .gitignore | Added German manual files to ignore list |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/web/server.py
Outdated
| language = request.args.get("lang") | ||
|
|
||
| if language: | ||
| file_name = "user-manual_" + language[:2] + ".html" |
Copilot
AI
Nov 1, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The language[:2] slicing without sanitization could allow path traversal attacks. An attacker could pass special characters or path sequences in the lang parameter (e.g., ?lang=../malicious). While os.path.exists() provides some protection, you should validate that language contains only alphanumeric characters before constructing the file name. Consider using language[:2].isalpha() or a regex pattern to validate the input.
src/web/server.py
Outdated
|
|
||
| if language: | ||
| file_name = "user-manual_" + language[:2] + ".html" | ||
| file_path = os.path.join(os.path.join(app.root_path, "static"), file_name) |
Copilot
AI
Nov 1, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The nested os.path.join() call is redundant. You can simplify this to os.path.join(app.root_path, 'static', file_name) which is more readable and achieves the same result.
src/web/server.py
Outdated
| language = request.args.get("lang") | ||
|
|
||
| if language: | ||
| file_name = "mobile-user-manual_" + language[:2] + ".html" |
Copilot
AI
Nov 1, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The language[:2] slicing without sanitization could allow path traversal attacks. An attacker could pass special characters or path sequences in the lang parameter (e.g., ?lang=../malicious). While os.path.exists() provides some protection, you should validate that language contains only alphanumeric characters before constructing the file name. Consider using language[:2].isalpha() or a regex pattern to validate the input.
src/web/server.py
Outdated
|
|
||
| if language: | ||
| file_name = "mobile-user-manual_" + language[:2] + ".html" | ||
| file_path = os.path.join(os.path.join(app.root_path, "static"), file_name) |
Copilot
AI
Nov 1, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The nested os.path.join() call is redundant. You can simplify this to os.path.join(app.root_path, 'static', file_name) which is more readable and achieves the same result.
src/web/server.py
Outdated
| @app.route("/subsurface-user-manual/") | ||
| def static_user_manual(): | ||
| language = request.args.get("lang") | ||
|
|
||
| if language: | ||
| file_name = "user-manual_" + language[:2] + ".html" | ||
| file_path = os.path.join(os.path.join(app.root_path, "static"), file_name) | ||
| if os.path.exists(file_path): | ||
| return send_from_directory(os.path.join(app.root_path, "static"), file_name) | ||
|
|
||
| return send_from_directory(os.path.join(app.root_path, "static"), "user-manual.html") | ||
|
|
||
|
|
||
| @app.route("/subsurface-mobile-v3-user-manual/") | ||
| @app.route("/subsurface-mobile-user-manual/") | ||
| def static_mobile_user_manual(): | ||
| language = request.args.get("lang") | ||
|
|
||
| if language: | ||
| file_name = "mobile-user-manual_" + language[:2] + ".html" | ||
| file_path = os.path.join(os.path.join(app.root_path, "static"), file_name) | ||
| if os.path.exists(file_path): | ||
| return send_from_directory(os.path.join(app.root_path, "static"), file_name) | ||
|
|
||
| return send_from_directory(os.path.join(app.root_path, "static"), "mobile-user-manual.html") | ||
|
|
||
|
|
Copilot
AI
Nov 1, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic for language-based file serving in static_user_manual() and static_mobile_user_manual() is duplicated. Consider extracting this into a helper function that takes the base filename as a parameter to reduce code duplication and improve maintainability.
| @app.route("/subsurface-user-manual/") | |
| def static_user_manual(): | |
| language = request.args.get("lang") | |
| if language: | |
| file_name = "user-manual_" + language[:2] + ".html" | |
| file_path = os.path.join(os.path.join(app.root_path, "static"), file_name) | |
| if os.path.exists(file_path): | |
| return send_from_directory(os.path.join(app.root_path, "static"), file_name) | |
| return send_from_directory(os.path.join(app.root_path, "static"), "user-manual.html") | |
| @app.route("/subsurface-mobile-v3-user-manual/") | |
| @app.route("/subsurface-mobile-user-manual/") | |
| def static_mobile_user_manual(): | |
| language = request.args.get("lang") | |
| if language: | |
| file_name = "mobile-user-manual_" + language[:2] + ".html" | |
| file_path = os.path.join(os.path.join(app.root_path, "static"), file_name) | |
| if os.path.exists(file_path): | |
| return send_from_directory(os.path.join(app.root_path, "static"), file_name) | |
| return send_from_directory(os.path.join(app.root_path, "static"), "mobile-user-manual.html") | |
| def _serve_user_manual(base_filename): | |
| language = request.args.get("lang") | |
| static_dir = os.path.join(app.root_path, "static") | |
| if language: | |
| file_name = f"{base_filename}_{language[:2]}.html" | |
| file_path = os.path.join(static_dir, file_name) | |
| if os.path.exists(file_path): | |
| return send_from_directory(static_dir, file_name) | |
| return send_from_directory(static_dir, f"{base_filename}.html") | |
| @app.route("/subsurface-user-manual/") | |
| def static_user_manual(): | |
| return _serve_user_manual("user-manual") | |
| @app.route("/subsurface-mobile-v3-user-manual/") | |
| @app.route("/subsurface-mobile-user-manual/") | |
| def static_mobile_user_manual(): | |
| return _serve_user_manual("mobile-user-manual") |
Add support for building and serving the German versions of the manual and mobile manual. Signed-off-by: Michael Keller <[email protected]>
e882fba to
89d2d9c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 2 out of 3 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if language and language[:2].isalpha(): | ||
| file_name = f"{base_filename}_{language[:2]}.html" | ||
| file_path = os.path.join(static_dir, file_name) | ||
| if os.path.exists(file_path): | ||
| return send_from_directory(static_dir, file_name) |
Copilot
AI
Nov 1, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The language parameter validation is insufficient and may allow path traversal attacks. While isalpha() checks if characters are alphabetic, it doesn't prevent sequences like ../. Use a whitelist approach by checking against the languages list defined in the module (lines 39-67), or at minimum use language[:2].isalpha() and language[:2].islower() and verify there are no special characters in the full language string before using it in file operations.
Add support for building and serving the German versions of the manual
and mobile manual.
Signed-off-by: Michael Keller [email protected]