From 665839133fa808d10697dfa7026beb982ae4b251 Mon Sep 17 00:00:00 2001 From: Jens L Date: Mon, 23 Nov 2020 20:50:19 +0100 Subject: [PATCH] Application Icon upload (#341) * core: add initial implementation for File Upload * root: add volumes to docker-compose for file upload * helm: add pvc for uploads * core: allow meta_icon to be overwritten with static files --- .gitignore | 3 ++- docker-compose.yml | 6 ++++- helm/templates/pvc.yaml | 15 ++++++++++++ helm/templates/static-deployment.yaml | 7 ++++++ helm/templates/web-deployment.yaml | 7 ++++++ passbook/core/api/applications.py | 2 +- passbook/core/forms/applications.py | 5 ++-- .../core/migrations/0015_application_icon.py | 24 +++++++++++++++++++ passbook/core/models.py | 3 ++- .../{overview/index.html => library.html} | 8 +++---- .../templates/partials/form_horizontal.html | 20 ++++++++++++++++ passbook/core/urls.py | 8 +++---- .../core/views/{overview.py => library.py} | 6 ++--- passbook/root/settings.py | 2 ++ passbook/root/urls.py | 9 ++++++- swagger.yaml | 6 +++-- website/docs/installation/kubernetes.md | 8 +++++++ website/docs/upgrading/to-0.13.md_ | 21 ++++++++++++++++ 18 files changed, 139 insertions(+), 21 deletions(-) create mode 100644 helm/templates/pvc.yaml create mode 100644 passbook/core/migrations/0015_application_icon.py rename passbook/core/templates/{overview/index.html => library.html} (93%) rename passbook/core/views/{overview.py => library.py} (84%) create mode 100644 website/docs/upgrading/to-0.13.md_ diff --git a/.gitignore b/.gitignore index ae7a6982b..89969089f 100644 --- a/.gitignore +++ b/.gitignore @@ -197,5 +197,6 @@ local.env.yml **/charts/*.tgz # Selenium Screenshots -selenium_screenshots/** +selenium_screenshots/ backups/ +media/ diff --git a/docker-compose.yml b/docker-compose.yml index 9ab0328ae..075b3ce4e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -25,6 +25,8 @@ services: PASSBOOK_REDIS__HOST: redis PASSBOOK_POSTGRESQL__HOST: postgresql PASSBOOK_POSTGRESQL__PASSWORD: ${PG_PASS} + volumes: + - ./media:/media ports: - 8000 networks: @@ -60,11 +62,13 @@ services: labels: traefik.enable: 'true' traefik.docker.network: internal - traefik.http.routers.static-router.rule: PathPrefix(`/static`, `/robots.txt`, `/favicon.ico`) + traefik.http.routers.static-router.rule: PathPrefix(`/static`, `/media`, `/robots.txt`, `/favicon.ico`) traefik.http.routers.static-router.tls: 'true' traefik.http.routers.static-router.service: static-service traefik.http.services.static-service.loadbalancer.healthcheck.path: / traefik.http.services.static-service.loadbalancer.server.port: '80' + volumes: + - ./media:/media traefik: image: traefik:2.3 command: diff --git a/helm/templates/pvc.yaml b/helm/templates/pvc.yaml new file mode 100644 index 000000000..dd42cb5c7 --- /dev/null +++ b/helm/templates/pvc.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "passbook.fullname" . }}-uploads + labels: + app.kubernetes.io/name: {{ include "passbook.name" . }} + helm.sh/chart: {{ include "passbook.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: 5Gi diff --git a/helm/templates/static-deployment.yaml b/helm/templates/static-deployment.yaml index f723d219f..08108b235 100644 --- a/helm/templates/static-deployment.yaml +++ b/helm/templates/static-deployment.yaml @@ -48,3 +48,10 @@ spec: limits: cpu: 20m memory: 20M + volumeMounts: + - name: passbook-uploads + mountPath: /usr/share/nginx/html/media + volumes: + - name: passbook-uploads + persistentVolumeClaim: + claimName: {{ include "passbook.fullname" . }}-uploads diff --git a/helm/templates/web-deployment.yaml b/helm/templates/web-deployment.yaml index 20f89bc9b..d87b2d1a0 100644 --- a/helm/templates/web-deployment.yaml +++ b/helm/templates/web-deployment.yaml @@ -90,6 +90,9 @@ spec: secretKeyRef: name: "{{ .Release.Name }}-postgresql" key: "postgresql-password" + volumeMounts: + - name: passbook-uploads + mountPath: /media ports: - name: http containerPort: 8000 @@ -115,3 +118,7 @@ spec: limits: cpu: 300m memory: 500M + volumes: + - name: passbook-uploads + persistentVolumeClaim: + claimName: {{ include "passbook.fullname" . }}-uploads diff --git a/passbook/core/api/applications.py b/passbook/core/api/applications.py index f75df3d16..bad813d81 100644 --- a/passbook/core/api/applications.py +++ b/passbook/core/api/applications.py @@ -22,7 +22,7 @@ class ApplicationSerializer(ModelSerializer): "slug", "provider", "meta_launch_url", - "meta_icon_url", + "meta_icon", "meta_description", "meta_publisher", "policies", diff --git a/passbook/core/forms/applications.py b/passbook/core/forms/applications.py index 01ae699bf..1e78f88ed 100644 --- a/passbook/core/forms/applications.py +++ b/passbook/core/forms/applications.py @@ -23,14 +23,13 @@ class ApplicationForm(forms.ModelForm): "slug", "provider", "meta_launch_url", - "meta_icon_url", + "meta_icon", "meta_description", "meta_publisher", ] widgets = { "name": forms.TextInput(), "meta_launch_url": forms.TextInput(), - "meta_icon_url": forms.TextInput(), "meta_publisher": forms.TextInput(), } help_texts = { @@ -44,7 +43,7 @@ class ApplicationForm(forms.ModelForm): field_classes = {"provider": GroupedModelChoiceField} labels = { "meta_launch_url": _("Launch URL"), - "meta_icon_url": _("Icon URL"), + "meta_icon": _("Icon"), "meta_description": _("Description"), "meta_publisher": _("Publisher"), } diff --git a/passbook/core/migrations/0015_application_icon.py b/passbook/core/migrations/0015_application_icon.py new file mode 100644 index 000000000..5db76b9ed --- /dev/null +++ b/passbook/core/migrations/0015_application_icon.py @@ -0,0 +1,24 @@ +# Generated by Django 3.1.3 on 2020-11-23 17:19 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("passbook_core", "0014_auto_20201018_1158"), + ] + + operations = [ + migrations.RemoveField( + model_name="application", + name="meta_icon_url", + ), + migrations.AddField( + model_name="application", + name="meta_icon", + field=models.FileField( + blank=True, default="", upload_to="application-icons/" + ), + ), + ] diff --git a/passbook/core/models.py b/passbook/core/models.py index cb639d3f3..da9da6afc 100644 --- a/passbook/core/models.py +++ b/passbook/core/models.py @@ -171,7 +171,8 @@ class Application(PolicyBindingModel): ) meta_launch_url = models.URLField(default="", blank=True) - meta_icon_url = models.TextField(default="", blank=True) + # For template applications, this can be set to /static/passbook/applications/* + meta_icon = models.FileField(upload_to="application-icons/", default="", blank=True) meta_description = models.TextField(default="", blank=True) meta_publisher = models.TextField(default="", blank=True) diff --git a/passbook/core/templates/overview/index.html b/passbook/core/templates/library.html similarity index 93% rename from passbook/core/templates/overview/index.html rename to passbook/core/templates/library.html index 0fd2d534b..a2f4d46a6 100644 --- a/passbook/core/templates/overview/index.html +++ b/passbook/core/templates/library.html @@ -13,12 +13,12 @@ {% if applications %} + {% elif field.field.widget|fieldtype == "ClearableFileInput" %} +
+ +
+
+
+
+
+
+ {{ field|css_class:"pf-c-form-control" }} +
+
+
+
+
{% else %}