From 96f5ee798a82cf07dc82fc33ac73e9153fbeb5af Mon Sep 17 00:00:00 2001 From: Martin Varga Date: Tue, 29 Apr 2025 13:56:06 +0200 Subject: [PATCH 1/5] Add example for local development with docker compose --- deployment/community/docker-compose.debug.yml | 51 +++++++++++++++++++ development.md | 9 ++++ 2 files changed, 60 insertions(+) create mode 100644 deployment/community/docker-compose.debug.yml diff --git a/deployment/community/docker-compose.debug.yml b/deployment/community/docker-compose.debug.yml new file mode 100644 index 00000000..09a88a6b --- /dev/null +++ b/deployment/community/docker-compose.debug.yml @@ -0,0 +1,51 @@ + + +services: + server: + image: server + build: + context: ../../server + dockerfile: Dockerfile + env_file: + - .prod.env + - .dev.env + environment: + - FLASK_ENV=development + - FLASK_DEBUG=1 + - GEVENT_SUPPORT=1 + command: ["pip install debugpy -t /tmp && python3 /tmp/debugpy --wait-for-client --listen 0.0.0.0:5678 -m flask run -h 0.0.0.0 -p 5000"] + ports: + - 5000:5000 + - 5678:5678 + volumes: + - ../../server/:/app + celery-beat: + image: celery-beat + build: + context: ../../server + dockerfile: Dockerfile + env_file: + - .prod.env + - .dev.env + celery-worker: + image: celery-worker + build: + context: ../../server + dockerfile: Dockerfile + env_file: + - .prod.env + - .dev.env + web: + image: merginmaps-frontend + build: + context: ../../web-app + dockerfile: Dockerfile + maildev: + image: maildev/maildev + container_name: merginmaps-maildev + restart: always + ports: + - 1080:1080 + - 1025:1025 + networks: + - merginmaps diff --git a/development.md b/development.md index b51c83d4..4e4a2bd3 100644 --- a/development.md +++ b/development.md @@ -69,6 +69,7 @@ If you want to run the whole stack locally, you can use the docker. Docker will cd deployment/community/ # Run the docker composition with the current Dockerfiles +cp .env.template .prod.env docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d # Give ownership of the ./projects folder to user that is running the gunicorn container @@ -94,6 +95,14 @@ docker exec -it merginmaps-server flask server send-check-email --email admin@e In docker-compose.dev.yml is started maildev/maildev image that can be used to test emails (see [https://github.com/maildev/maildev/](https://github.com/maildev/maildev/)). In localhost:1080 you can see the emails sent by the application in web interface. +### Running with remote debugger +If you want to run the application with remote debugger, you can use debug compose file with attatched source code and reload. +It starts a debugpy session on port 5678 you cat attach to. + +```shell +docker compose -f docker-compose.yml -f docker-compose.debug.yml up +``` + ## Running tests To launch the unit tests run: ```shell From a7f47b0ee2bdd5bb758438a7a332f5151bfbfab8 Mon Sep 17 00:00:00 2001 From: Enock Seth Nyamador Date: Fri, 2 May 2025 14:36:13 +0200 Subject: [PATCH 2/5] fix typo --- development.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/development.md b/development.md index 21fd826c..b2a1be08 100644 --- a/development.md +++ b/development.md @@ -99,7 +99,7 @@ In docker-compose.dev.yml is started maildev/maildev image that can be used to t ### Running with remote debugger If you want to run the application with remote debugger, you can use debug compose file with attatched source code and reload. -It starts a debugpy session on port 5678 you cat attach to. +It starts a debugpy session on port 5678 you can attach to. ```shell docker compose -f docker-compose.yml -f docker-compose.debug.yml up From 7c2f4489d42992d5ee07535b04ecc0ba3be44c95 Mon Sep 17 00:00:00 2001 From: "marcel.kocisek" Date: Fri, 2 May 2025 15:17:07 +0200 Subject: [PATCH 3/5] use quote to encode filenames with special chars :japan --- server/mergin/sync/private_api_controller.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/mergin/sync/private_api_controller.py b/server/mergin/sync/private_api_controller.py index 44018c02..aaa77216 100644 --- a/server/mergin/sync/private_api_controller.py +++ b/server/mergin/sync/private_api_controller.py @@ -3,6 +3,7 @@ # SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-MerginMaps-Commercial import os from datetime import datetime, timedelta, timezone +from urllib.parse import quote from blinker import signal from connexion import NoContent from flask import ( @@ -347,8 +348,9 @@ def download_project(id: str, version=None): # noqa: E501 # pylint: disable=W06 else: resp = send_file(project_version.zip_path, mimetype="application/zip") + file_name = quote(f"{project.name}-v{lookup_version}.zip".encode("utf-8")) resp.headers["Content-Disposition"] = ( - f"attachment; filename={project.name}-v{lookup_version}.zip" + f"attachment; filename*=UTF-8''{file_name}" ) return resp From 7a1164c98696a266835c769a5b217df686bcda96 Mon Sep 17 00:00:00 2001 From: Enock Seth Nyamador Date: Mon, 5 May 2025 13:43:17 +0200 Subject: [PATCH 4/5] sign --- LICENSES/CLA-signed-list.md | 1 + 1 file changed, 1 insertion(+) diff --git a/LICENSES/CLA-signed-list.md b/LICENSES/CLA-signed-list.md index 627b7e57..bd7ccdfe 100644 --- a/LICENSES/CLA-signed-list.md +++ b/LICENSES/CLA-signed-list.md @@ -4,6 +4,7 @@ A/ You have read and agree to the individual CLA: https://merginmaps.com/license * `alhirzel`, 20th December 2023 * `uprel`, 18th March 2024 +* `enockseth`, 5th May 2025 B/ I have read and agree with entity CLA for my company: https://merginmaps.com/licenses/entity-cla From d1ba52d88cd46407fc5509ac516b9fb2006de68b Mon Sep 17 00:00:00 2001 From: "marcel.kocisek" Date: Mon, 5 May 2025 15:06:37 +0200 Subject: [PATCH 5/5] Closing and reopening new download progress bar --- web-app/packages/lib/src/modules/project/store.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/web-app/packages/lib/src/modules/project/store.ts b/web-app/packages/lib/src/modules/project/store.ts index 5cf79fb2..182bdea2 100644 --- a/web-app/packages/lib/src/modules/project/store.ts +++ b/web-app/packages/lib/src/modules/project/store.ts @@ -708,11 +708,9 @@ export const useProjectStore = defineStore('projectModule', { async downloadArchive(payload: DownloadPayload) { const notificationStore = useNotificationStore() - this.cancelDownloadArchive() + await this.cancelDownloadArchive() + this.projectDownloadingVersion = payload.versionId this.projectDownloading = true - if (payload.versionId) { - this.projectDownloadingVersion = payload.versionId - } const errorMessage = 'Failed to download project archive. Please try again later.' @@ -728,7 +726,7 @@ export const useProjectStore = defineStore('projectModule', { text: exceedMessage, life: 6000 }) - this.cancelDownloadArchive() + await this.cancelDownloadArchive() return } @@ -765,7 +763,7 @@ export const useProjectStore = defineStore('projectModule', { pollDownloadArchive() }, - cancelDownloadArchive() { + async cancelDownloadArchive() { if (downloadArchiveTimeout) { clearTimeout(downloadArchiveTimeout) downloadArchiveTimeout = null