aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/administration/configuration.rst6
-rw-r--r--fietsboek/actions.py11
-rw-r--r--fietsboek/config.py3
-rw-r--r--fietsboek/locale/de/LC_MESSAGES/messages.mobin15259 -> 15377 bytes
-rw-r--r--fietsboek/locale/de/LC_MESSAGES/messages.po27
-rw-r--r--fietsboek/locale/en/LC_MESSAGES/messages.mobin14269 -> 14369 bytes
-rw-r--r--fietsboek/locale/en/LC_MESSAGES/messages.po27
-rw-r--r--fietsboek/locale/fietslog.pot20
-rw-r--r--fietsboek/templates/edit_form.jinja29
-rw-r--r--tests/conftest.py9
-rw-r--r--tests/playwright/conftest.py4
-rw-r--r--tests/playwright/test_no_image_uploads.py34
12 files changed, 112 insertions, 38 deletions
diff --git a/doc/administration/configuration.rst b/doc/administration/configuration.rst
index 5be3537..4d33b7f 100644
--- a/doc/administration/configuration.rst
+++ b/doc/administration/configuration.rst
@@ -42,13 +42,17 @@ Most of the configuration is in the ``[app:main]`` category and looks like this:
General Settings
----------------
-Use ``enable_account_registration`` enable or disable the creation of new
+Use ``enable_account_registration`` to enable or disable the creation of new
accounts via the web interface, for example if you want to have a private
instance. New accounts can always be created using the CLI management tool.
Set ``session_key`` to a random string of characters. This is the key used to
sign session data, so it should not get into wrong hands!
+Use ``fietsboek.enable_image_uploads`` to enable or disable image uploads. By
+default, track uploaders can add images to the track. Set this setting to
+``false`` to disable this feature.
+
You can set up custom pages using ``fietsboek.pages``. See :doc:`custom-pages`
for more information.
diff --git a/fietsboek/actions.py b/fietsboek/actions.py
index 7e83c22..439a8cd 100644
--- a/fietsboek/actions.py
+++ b/fietsboek/actions.py
@@ -139,7 +139,7 @@ def edit_images(request: Request, track: models.Track, *, manager: Optional[Trac
if image_meta:
request.dbsession.delete(image_meta)
- # Add new images
+ # Add new images, but only if the setting allows for it
set_descriptions = set()
for param_name, image in request.params.items():
match = re.match("image\\[(\\d+)\\]$", param_name)
@@ -150,6 +150,15 @@ def edit_images(request: Request, track: models.Track, *, manager: Optional[Trac
continue
upload_id = match.group(1)
+
+ # If the uploads are disabled, we still add the image to
+ # set_descriptions so that later down below we don't try to set the
+ # description for it.
+ if not request.config.enable_image_uploads:
+ set_descriptions.add(upload_id)
+ LOGGER.debug("Tried to upload image but uploads are disabled (track %s)", track.id)
+ continue
+
image_name = manager.add_image(image.file, image.filename)
image_meta = models.ImageMetadata(track=track, image_name=image_name)
image_meta.description = request.params.get(f"image-description[{upload_id}]", "")
diff --git a/fietsboek/config.py b/fietsboek/config.py
index 6cb1f04..c3c31c8 100644
--- a/fietsboek/config.py
+++ b/fietsboek/config.py
@@ -148,6 +148,9 @@ class Config(BaseModel):
enable_account_registration: bool = False
"""Enable registration of new accounts."""
+ enable_image_uploads: bool = Field(True, alias="fietsboek.enable_image_uploads")
+ """Allow track uploaders to also upload images for tracks."""
+
session_key: str
"""Session key."""
diff --git a/fietsboek/locale/de/LC_MESSAGES/messages.mo b/fietsboek/locale/de/LC_MESSAGES/messages.mo
index f2bf3ea..3c020df 100644
--- a/fietsboek/locale/de/LC_MESSAGES/messages.mo
+++ b/fietsboek/locale/de/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/fietsboek/locale/de/LC_MESSAGES/messages.po b/fietsboek/locale/de/LC_MESSAGES/messages.po
index 69723be..24e1cb5 100644
--- a/fietsboek/locale/de/LC_MESSAGES/messages.po
+++ b/fietsboek/locale/de/LC_MESSAGES/messages.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2023-09-14 20:05+0200\n"
+"POT-Creation-Date: 2023-11-10 22:23+0100\n"
"PO-Revision-Date: 2022-07-02 17:35+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: de\n"
@@ -18,11 +18,11 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.12.1\n"
-#: fietsboek/actions.py:255
+#: fietsboek/actions.py:257
msgid "email.verify_mail.subject"
msgstr "Fietsboek Konto Bestätigung"
-#: fietsboek/actions.py:258
+#: fietsboek/actions.py:260
msgid "email.verify.text"
msgstr ""
"Um Dein Fietsboek-Konto zu bestätigen, nutze diesen Link: {}\n"
@@ -471,23 +471,27 @@ msgid "page.track.form.description"
msgstr "Beschreibung"
#: fietsboek/templates/edit_form.jinja2:108
-#: fietsboek/templates/edit_form.jinja2:122
+#: fietsboek/templates/edit_form.jinja2:129
msgid "page.track.form.remove_image"
msgstr "Bild entfernen"
-#: fietsboek/templates/edit_form.jinja2:117
+#: fietsboek/templates/edit_form.jinja2:118
msgid "page.track.form.select_images"
msgstr "Bilder auswählen"
-#: fietsboek/templates/edit_form.jinja2:133
+#: fietsboek/templates/edit_form.jinja2:122
+msgid "page.track.form.image_uploads_disabled"
+msgstr "Das Hochladen von Bildern ist auf diesem Fietsboek deaktiviert"
+
+#: fietsboek/templates/edit_form.jinja2:140
msgid "page.track.form.image_description_modal"
msgstr "Bildbeschreibung"
-#: fietsboek/templates/edit_form.jinja2:140
+#: fietsboek/templates/edit_form.jinja2:147
msgid "page.track.form.image_description_modal.save"
msgstr "Übernehmen"
-#: fietsboek/templates/edit_form.jinja2:166
+#: fietsboek/templates/edit_form.jinja2:173
msgid "page.track.form.transformer.enable"
msgstr "Transformation anwenden"
@@ -759,9 +763,10 @@ msgstr "Sitzungen abmelden"
#: fietsboek/templates/user_data.jinja2:40
msgid "page.my_profile.session_logout.explanation"
msgstr ""
-"Mit dieser Funktion können alle Sitzungen beendet werden. Dies ist nützlich, "
-"wenn Du vergessen hast, dich auf einem fremden Gerät abzumelden. Beachte, dass "
-"Du dich erneut anmelden musst, wenn Du diese Funktion nutzt!"
+"Mit dieser Funktion können alle Sitzungen beendet werden. Dies ist "
+"nützlich, wenn Du vergessen hast, dich auf einem fremden Gerät "
+"abzumelden. Beachte, dass Du dich erneut anmelden musst, wenn Du diese "
+"Funktion nutzt!"
#: fietsboek/templates/user_data.jinja2:44
msgid "page.my_profile.session_logout.button"
diff --git a/fietsboek/locale/en/LC_MESSAGES/messages.mo b/fietsboek/locale/en/LC_MESSAGES/messages.mo
index da23e31..c03929b 100644
--- a/fietsboek/locale/en/LC_MESSAGES/messages.mo
+++ b/fietsboek/locale/en/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/fietsboek/locale/en/LC_MESSAGES/messages.po b/fietsboek/locale/en/LC_MESSAGES/messages.po
index 45b15cc..f5a7874 100644
--- a/fietsboek/locale/en/LC_MESSAGES/messages.po
+++ b/fietsboek/locale/en/LC_MESSAGES/messages.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2023-09-14 20:05+0200\n"
+"POT-Creation-Date: 2023-11-10 22:23+0100\n"
"PO-Revision-Date: 2023-04-03 20:42+0200\n"
"Last-Translator: \n"
"Language: en\n"
@@ -18,11 +18,11 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.12.1\n"
-#: fietsboek/actions.py:255
+#: fietsboek/actions.py:257
msgid "email.verify_mail.subject"
msgstr "Fietsboek Account Verification"
-#: fietsboek/actions.py:258
+#: fietsboek/actions.py:260
msgid "email.verify.text"
msgstr ""
"To verify your Fietsboek account, please use this link: {}\n"
@@ -467,23 +467,27 @@ msgid "page.track.form.description"
msgstr "Description"
#: fietsboek/templates/edit_form.jinja2:108
-#: fietsboek/templates/edit_form.jinja2:122
+#: fietsboek/templates/edit_form.jinja2:129
msgid "page.track.form.remove_image"
msgstr "Remove image"
-#: fietsboek/templates/edit_form.jinja2:117
+#: fietsboek/templates/edit_form.jinja2:118
msgid "page.track.form.select_images"
msgstr "Select images"
-#: fietsboek/templates/edit_form.jinja2:133
+#: fietsboek/templates/edit_form.jinja2:122
+msgid "page.track.form.image_uploads_disabled"
+msgstr "Image uploads are disabled on this Fietsboek"
+
+#: fietsboek/templates/edit_form.jinja2:140
msgid "page.track.form.image_description_modal"
msgstr "Image description"
-#: fietsboek/templates/edit_form.jinja2:140
+#: fietsboek/templates/edit_form.jinja2:147
msgid "page.track.form.image_description_modal.save"
msgstr "Apply"
-#: fietsboek/templates/edit_form.jinja2:166
+#: fietsboek/templates/edit_form.jinja2:173
msgid "page.track.form.transformer.enable"
msgstr "Apply transformation"
@@ -753,9 +757,10 @@ msgstr "Invalidate sessions"
#: fietsboek/templates/user_data.jinja2:40
msgid "page.my_profile.session_logout.explanation"
msgstr ""
-"With this functionality, you can force all of your current sessions "
-"to be logged out. This is useful when you forgot to log out on a foreign "
-"device. Note that you will have to log in again after using this function."
+"With this functionality, you can force all of your current sessions to be"
+" logged out. This is useful when you forgot to log out on a foreign "
+"device. Note that you will have to log in again after using this "
+"function."
#: fietsboek/templates/user_data.jinja2:44
msgid "page.my_profile.session_logout.button"
diff --git a/fietsboek/locale/fietslog.pot b/fietsboek/locale/fietslog.pot
index b87785e..e5a0b40 100644
--- a/fietsboek/locale/fietslog.pot
+++ b/fietsboek/locale/fietslog.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2023-09-14 20:05+0200\n"
+"POT-Creation-Date: 2023-11-10 22:23+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,11 +17,11 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.12.1\n"
-#: fietsboek/actions.py:255
+#: fietsboek/actions.py:257
msgid "email.verify_mail.subject"
msgstr ""
-#: fietsboek/actions.py:258
+#: fietsboek/actions.py:260
msgid "email.verify.text"
msgstr ""
@@ -461,23 +461,27 @@ msgid "page.track.form.description"
msgstr ""
#: fietsboek/templates/edit_form.jinja2:108
-#: fietsboek/templates/edit_form.jinja2:122
+#: fietsboek/templates/edit_form.jinja2:129
msgid "page.track.form.remove_image"
msgstr ""
-#: fietsboek/templates/edit_form.jinja2:117
+#: fietsboek/templates/edit_form.jinja2:118
msgid "page.track.form.select_images"
msgstr ""
-#: fietsboek/templates/edit_form.jinja2:133
-msgid "page.track.form.image_description_modal"
+#: fietsboek/templates/edit_form.jinja2:122
+msgid "page.track.form.image_uploads_disabled"
msgstr ""
#: fietsboek/templates/edit_form.jinja2:140
+msgid "page.track.form.image_description_modal"
+msgstr ""
+
+#: fietsboek/templates/edit_form.jinja2:147
msgid "page.track.form.image_description_modal.save"
msgstr ""
-#: fietsboek/templates/edit_form.jinja2:166
+#: fietsboek/templates/edit_form.jinja2:173
msgid "page.track.form.transformer.enable"
msgstr ""
diff --git a/fietsboek/templates/edit_form.jinja2 b/fietsboek/templates/edit_form.jinja2
index 1abe076..43f3400 100644
--- a/fietsboek/templates/edit_form.jinja2
+++ b/fietsboek/templates/edit_form.jinja2
@@ -114,7 +114,14 @@
{% endfor %}
</div>
<input type="file" name="image[]" id="imageSelector" class="form-control" accept="image/*" style="display:none;" multiple>
- <button type="button" onclick="document.querySelector('#imageSelector').click()" class="btn btn-primary"><i class="bi bi-images"></i> {{ _("page.track.form.select_images") }}</button>
+ <button type="button" onclick="document.querySelector('#imageSelector').click()" class="btn btn-primary" id="selectImagesButton" {% if not request.config.enable_image_uploads %}disabled{% endif %}>
+ <i class="bi bi-images"></i> {{ _("page.track.form.select_images") }}
+ </button>
+ {% if not request.config.enable_image_uploads %}
+ <span class="text-info">
+ <i class="bi bi-info-circle-fill"></i> {{ _("page.track.form.image_uploads_disabled") }}
+ </span>
+ {% endif %}
</div>
<!-- Mode hidden templates -->
<div style="display:none;">
diff --git a/tests/conftest.py b/tests/conftest.py
index a4366ab..94f795a 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -28,11 +28,14 @@ def ini_file(request):
# potentially grab this path from a pytest option
return os.path.abspath(request.config.option.ini or 'testing.ini')
-@pytest.fixture(scope='session')
+# Even though the ini file is scoped to session, we scope the actual settings
+# to module only. This way, we can test different configurations in different
+# modules.
+@pytest.fixture(scope='module')
def app_settings(ini_file):
return get_appsettings(ini_file)
-@pytest.fixture(scope='session')
+@pytest.fixture(scope='module')
def dbengine(app_settings, ini_file):
engine = models.get_engine(app_settings)
@@ -73,7 +76,7 @@ def _cleanup_data(app_settings):
if (data_dir / "tracks").is_dir():
shutil.rmtree(data_dir / "tracks")
-@pytest.fixture(scope='session')
+@pytest.fixture(scope='module')
def app(app_settings, dbengine, tmp_path_factory):
app_settings["fietsboek.data_dir"] = str(tmp_path_factory.mktemp("data"))
logging.getLogger().setLevel(logging.DEBUG)
diff --git a/tests/playwright/conftest.py b/tests/playwright/conftest.py
index 12a0047..4e7f5a4 100644
--- a/tests/playwright/conftest.py
+++ b/tests/playwright/conftest.py
@@ -15,7 +15,7 @@ from fietsboek.config import Config
import pytest
-@pytest.fixture(scope="session")
+@pytest.fixture(scope="module")
def server_port():
"""Return a (likely) free port.
@@ -29,7 +29,7 @@ def server_port():
return port
-@pytest.fixture(scope="session", autouse=True)
+@pytest.fixture(scope="module", autouse=True)
def running_server(server_port, app):
"""Have the app running as an actual server."""
server = simple_server.make_server("127.0.0.1", server_port, app)
diff --git a/tests/playwright/test_no_image_uploads.py b/tests/playwright/test_no_image_uploads.py
new file mode 100644
index 0000000..b133697
--- /dev/null
+++ b/tests/playwright/test_no_image_uploads.py
@@ -0,0 +1,34 @@
+import pytest
+from playwright.sync_api import Page, expect
+
+from testutils import extract_and_upload
+
+
+@pytest.fixture(scope="module")
+def app_settings(app_settings):
+ """Override the standard app settings to disable image uploads."""
+ app_settings["fietsboek.enable_image_uploads"] = "false"
+ return app_settings
+
+
+def test_image_button_disabled_during_upload(page: Page, playwright_helper, tmp_path, dbaccess):
+ playwright_helper.login()
+
+ page.goto("/")
+ page.get_by_text("Upload").click()
+
+ # We unpack one of the test GPX files
+ extract_and_upload(page, "Teasi_1.gpx.gz", tmp_path)
+
+ # We now fill in most of the data
+ expect(page.locator("#selectImagesButton")).to_be_disabled()
+
+
+def test_image_button_disabled_during_edit(page: Page, playwright_helper, dbaccess):
+ playwright_helper.login()
+ track_id = playwright_helper.add_track().id
+
+ page.goto(f"/track/{track_id}")
+ page.locator(".btn", has_text="Edit").click()
+
+ expect(page.locator("#selectImagesButton")).to_be_disabled()