diff --git a/client/src/components/ui/WagtailImage.vue b/client/src/components/ui/WagtailImage.vue index 1ad4b225..bade9c11 100644 --- a/client/src/components/ui/WagtailImage.vue +++ b/client/src/components/ui/WagtailImage.vue @@ -4,6 +4,7 @@ :src="modifiedUrl" :alt="alt" class="wagtail-image__image" + loading="eager" v-show="loaded" ref="imgElement" @load="loaded = true" @@ -85,15 +86,20 @@ onMounted(updateDimensions); @import 'styles/helpers'; .wagtail-image { - max-width: 100%; + overflow: hidden; + &__image { - max-width: 100%; + width: 100%; + height: auto; /* Keep the image's aspect ratio intact */ + min-height: 100%; + } &__placeholder { background-color: $color-silver-light; - max-width: 100%; + width: 100%; + height: 100%; } } diff --git a/local-setup-for-cypress-tests.sh b/local-setup-for-cypress-tests.sh new file mode 100755 index 00000000..43f4ca1f --- /dev/null +++ b/local-setup-for-cypress-tests.sh @@ -0,0 +1,33 @@ +#!/bin/bash +#!/bin/bash +export SECRET_KEY=abcd1234 +export DATABASE_HOST=localhost +export DATABASE_USER=postgres +export PGPASSWORD=postgres +export DATABASE_NAME=skillbox_test_cypress +export DATABASE_PORT=5432 +export DATABASE_URL=postgres://$DATABASE_USER:$PGPASSWORD@$DATABASE_HOST:$DATABASE_PORT/$DATABASE_NAME +export DEBUG=True +export USE_AWS=False +export SERVE_VIA_WEBPACK=False +export OAUTH_CLIENT_ID=1111111-222222-333-3444444 +export OAUTH_CLIENT_SECRET=Abcd1234! +export OAUTH_ACCESS_TOKEN_URL=https://hepverlag-cms.grape.novu.ch/oauth/token +export OAUTH_AUTHORIZE_URL=https://hepverlag-cms.grape.novu.ch/oauth/authorize +export OAUTH_API_BASE_URL=https://hepverlag-cms.grape.novu.ch/ +export OAUTH_LOCAL_REDIRECT_URI=http://localhost:8000/api/oauth/callback/ +export NODE_OPTIONS=--max_old_space_size=3072 + +export DATABASE_HOST=localhost +export DATABASE_PORT=5432 +export DATABASE_URL=postgres://$DATABASE_USER:$PG_PASSWORD@$DATABASE_HOST:$DATABASE_PORT/$DATABASE_NAME +psql -U $DATABASE_USER -h $DATABASE_HOST -c "drop database $DATABASE_NAME" + +#npm install --prefix client +#npm run "install:cypress" --prefix client +psql -U $DATABASE_USER -h $DATABASE_HOST -c "create database $DATABASE_NAME" +python server/manage.py dummy_data +python server/manage.py runserver & +npm run dev --prefix client & +cd client +/node_modules/.bin/cypress run diff --git a/server/api/graphene_wagtail.py b/server/api/graphene_wagtail.py index da60dfce..3f00156d 100644 --- a/server/api/graphene_wagtail.py +++ b/server/api/graphene_wagtail.py @@ -12,6 +12,7 @@ from wagtail.images.models import Image from assignments.models import Assignment from basicknowledge.models import BasicKnowledge from books.models import CustomDocument +from core.wagtail_image import get_image_json from surveys.models import Survey logger = logging.getLogger(__name__) @@ -49,9 +50,7 @@ def augment_fields(raw_data): if _type == 'image_block': _value = data['value'] image = Image.objects.get(id=_value) - value = { - 'path': generate_image_url(image, 'original'), - } + value = get_image_json(image.id) data['value'] = value if _type == 'assignment': _value = data['value'] diff --git a/server/core/urls.py b/server/core/urls.py index 25bce87f..c4a8ab2d 100644 --- a/server/core/urls.py +++ b/server/core/urls.py @@ -7,19 +7,19 @@ from wagtail.admin import urls as wagtailadmin_urls from wagtail import urls as wagtail_urls from wagtail.documents import urls as wagtaildocs_urls #from wagtail.images import urls as wagtailimages_urls -from wagtail.images.views.serve import ServeView +from core.views import CustomImageServeView from wagtailautocomplete.urls.admin import urlpatterns as autocomplete_admin_urls from core import views -from core.views import override_wagtailadmin_explore_default_ordering, user_image +from core.views import override_wagtailadmin_explore_default_ordering urlpatterns = [ # django admin re_path(r"^guru/", admin.site.urls), re_path(r"^statistics/", include("statistics.urls", namespace="statistics")), # wagtail - re_path(r'^api/images/([^/]*)/(\d*)/([^/]*)/[^/]*$', ServeView.as_view(action='redirect'), name='wagtailimages_serve'), + re_path(r'^api/images/([^/]*)/(\d*)/([^/]*)/[^/]*$', CustomImageServeView.as_view(action='redirect'), name='wagtailimages_serve'), re_path(r"^cms/autocomplete/", include(autocomplete_admin_urls)), re_path(r"^cms/pages/(\d+)/$", override_wagtailadmin_explore_default_ordering), diff --git a/server/core/views.py b/server/core/views.py index e808a13f..e489c49c 100644 --- a/server/core/views.py +++ b/server/core/views.py @@ -1,15 +1,31 @@ +import imghdr +from wsgiref.util import FileWrapper + import requests -from core.logger import get_logger from django.conf import settings +from django.contrib.auth.decorators import login_required from django.contrib.auth.mixins import LoginRequiredMixin +from django.core.exceptions import PermissionDenied +from django.http import HttpResponse, StreamingHttpResponse from django.http.request import HttpRequest -from django.http.response import HttpResponse, HttpResponseRedirect +from django.http.response import HttpResponseRedirect +from django.shortcuts import get_object_or_404 from django.shortcuts import render +from django.utils.decorators import method_decorator +from django.views.decorators.cache import cache_control from django.views.decorators.csrf import ensure_csrf_cookie from graphene_django.views import GraphQLView from graphql import get_operation_ast, parse from sentry_sdk.api import start_transaction from wagtail.admin.views.pages import listing +from wagtail.images import get_image_model +from wagtail.images.exceptions import InvalidFilterSpecError +from wagtail.images.models import Image +from wagtail.images.models import SourceImageIOError +from wagtail.images.utils import verify_signature +from wagtail.images.views.serve import ServeView + +from core.logger import get_logger logger = get_logger(__name__) @@ -68,3 +84,37 @@ def override_wagtailadmin_explore_default_ordering(request, parent_page_id): return HttpResponseRedirect(request.path_info + "?ordering=ord") return listing.IndexView.as_view()(request, parent_page_id) + +class CustomImageServeView(ServeView): + ''' Taken from wagtail.images.views.serve.ServeView the only change is that we use original for the filter_spec_for_signature''' + model = get_image_model() + action = "serve" + key = None + + @method_decorator(cache_control(max_age=3600, public=True)) + def get(self, request, signature, image_id, filter_spec, filename=None): + # This variable is the only change to the wagtail implementation + filter_spec_for_signature = 'original' + + if not verify_signature( + signature.encode(), image_id, filter_spec_for_signature, key=self.key + ): + raise PermissionDenied + + image = get_object_or_404(self.model, id=image_id) + + # Get/generate the rendition + try: + rendition = image.get_rendition(filter_spec) + except SourceImageIOError: + return HttpResponse( + "Source image file not found", content_type="text/plain", status=410 + ) + except InvalidFilterSpecError: + return HttpResponse( + "Invalid filter spec: " + filter_spec, + content_type="text/plain", + status=400, + ) + + return getattr(self, self.action)(rendition) diff --git a/server/core/wagtail_image.py b/server/core/wagtail_image.py new file mode 100644 index 00000000..e69de29b