From 65b51f89756d699cc1edc2022c7f09c897d87c40 Mon Sep 17 00:00:00 2001 From: Sean Engelhardt Date: Wed, 5 Apr 2017 15:46:44 +0200 Subject: [PATCH] Add local convert to Base64 (Fixes #2705) --- CHANGELOG | 2 + openslides/core/static/js/core/pdf.js | 19 +++++++ openslides/core/urls.py | 4 -- openslides/core/views.py | 56 --------------------- openslides/motions/static/js/motions/pdf.js | 25 +++++++-- 5 files changed, 41 insertions(+), 65 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index c6cb8ac59..5078fc656 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -15,6 +15,8 @@ Motions: - Fixed issue when creating/deleting motion comment fields in the settings [#3187]. - Fixed empty motion comment field in motion update form [#3194]. +- Removed server side image to base64 transformation and + added local transformation [#2705] Core: - No reload on logoff. OpenSlides is now a full single page diff --git a/openslides/core/static/js/core/pdf.js b/openslides/core/static/js/core/pdf.js index 139ac8160..e518607e4 100644 --- a/openslides/core/static/js/core/pdf.js +++ b/openslides/core/static/js/core/pdf.js @@ -87,6 +87,25 @@ angular.module('OpenSlidesApp.core.pdf', []) return '{{ballot-placeholder-to-insert-functions-here}}'; }; + // returns a promise for converting an image in data URL format + PDFLayout.imageURLtoBase64 = function(url) { + var promise = new Promise(function(resolve) { + var img = new Image(); + img.crossOrigin = "Anonymous"; + img.onload = function() { + var canvas = document.createElement("canvas"); + canvas.width = img.width; + canvas.height = img.height; + var ctx = canvas.getContext("2d"); + ctx.drawImage(img, 0, 0); + var dataURL = canvas.toDataURL("image/png"); + resolve(dataURL); + }; + img.src = url; + }); + return promise; + }; + return PDFLayout; } ]) diff --git a/openslides/core/urls.py b/openslides/core/urls.py index 356dd642c..7d5fcbe7c 100644 --- a/openslides/core/urls.py +++ b/openslides/core/urls.py @@ -11,10 +11,6 @@ urlpatterns = [ views.VersionView.as_view(), name='core_version'), - url(r'^core/encode_media/$', - views.MediaEncoder.as_view(), - name="core_mediaencoding"), - url(r'^webclient/(?Psite|projector)/$', views.WebclientJavaScriptView.as_view(), name='core_webclient_javascript'), diff --git a/openslides/core/views.py b/openslides/core/views.py index e0757501b..8853c7f51 100644 --- a/openslides/core/views.py +++ b/openslides/core/views.py @@ -1,6 +1,4 @@ -import base64 import json -import os import uuid from collections import OrderedDict from operator import attrgetter @@ -811,57 +809,3 @@ class VersionView(utils_views.APIView): 'description': get_plugin_description(plugin), 'version': get_plugin_version(plugin)}) return result - - -class MediaEncoder(utils_views.APIView): - """ - MediaEncoder is a class based view to prepare encoded media for pdfMake - """ - http_method_names = ['post'] - - def post(self, request, *args, **kwargs): - """ - Encode_image is used in the context of PDF-Generation - Takes an array of IMG.src - Paths - Retrieves the according images - Encodes the images to BASE64 - Puts it into a key-value structure - - { - "images": { - "media/file/ubuntu.png":"$ENCODED_IMAGE" - } - } - - :param request: - :return: Response of the resulting dictionary - - Calling e.g. - $.ajax({ type: "POST", url: "/motions/encode_images/", - data: JSON.stringify(["$FILEPATH"]), - success: function(data){ console.log(data); }, - dataType: 'application/json' }); - """ - body_unicode = request.body.decode('utf-8') - file_paths = json.loads(body_unicode) - images = {file_path: self.encode_image_from(file_path) for file_path in file_paths} - return Response({ - "images": images - }) - - def encode_image_from(self, file_path): - """ - Returns the BASE64 encoded version of an image-file for a given path - :param file_path: - :return: - """ - path = os.path.join(settings.MEDIA_ROOT, 'file', os.path.basename(file_path)) - try: - with open(path, "rb") as file: - string_representation = "data:image/{};base64,{}".format(os.path.splitext(file_path)[1][1:], - base64.b64encode(file.read()).decode()) - except Exception: - # If any error occurs ignore it and return an empty string - return "" - else: - return string_representation diff --git a/openslides/motions/static/js/motions/pdf.js b/openslides/motions/static/js/motions/pdf.js index 1376907ff..9f7501e64 100644 --- a/openslides/motions/static/js/motions/pdf.js +++ b/openslides/motions/static/js/motions/pdf.js @@ -613,9 +613,11 @@ angular.module('OpenSlidesApp.motions.pdf', ['OpenSlidesApp.core.pdf']) 'PollContentProvider', 'PdfMakeBallotPaperProvider', 'PdfCreate', + 'PDFLayout', + '$q', function ($http, Config, gettextCatalog, MotionChangeRecommendation, HTMLValidizer, PdfMakeConverter, MotionContentProvider, MotionCatalogContentProvider, PdfMakeDocumentProvider, PollContentProvider, - PdfMakeBallotPaperProvider, PdfCreate) { + PdfMakeBallotPaperProvider, PdfCreate, PDFLayout, $q) { return { export: function (motions, params, singleMotion) { if (!params) { @@ -657,9 +659,22 @@ angular.module('OpenSlidesApp.motions.pdf', ['OpenSlidesApp.core.pdf']) image_sources = image_sources.concat(tmp_image_sources); }); - //post-request to convert the images. Async. - $http.post('/core/encode_media/', JSON.stringify(image_sources)).then(function (success) { - var converter = PdfMakeConverter.createInstance(success.data.images); + var image_map = {}; + _.forEach(image_sources, function (image_source) { + image_map[image_source] = PDFLayout.imageURLtoBase64(image_source); + }); + + var image_promises = Object.keys(image_map).map(function( key ) { + return image_map[key]; + }); + + //resolv promises to get base64 + $q.all(image_promises).then(function(base64Str) { + Object.keys(image_map).map(function(key, i) { + image_map[key] = base64Str[i]; + }); + + var converter = PdfMakeConverter.createInstance(image_map); var motionContentProviderArray = []; //convert all motions to motionContentProviders @@ -671,7 +686,7 @@ angular.module('OpenSlidesApp.motions.pdf', ['OpenSlidesApp.core.pdf']) params.includeReason, params.includeComments )); }); - + var documentProvider; if (singleMotion) { documentProvider = PdfMakeDocumentProvider.createInstance(motionContentProviderArray[0]);