Add local convert to Base64 (Fixes #2705)

This commit is contained in:
Sean Engelhardt 2017-04-05 15:46:44 +02:00
parent b9bab6fc17
commit 65b51f8975
5 changed files with 41 additions and 65 deletions

View File

@ -15,6 +15,8 @@ Motions:
- Fixed issue when creating/deleting motion comment fields in the - Fixed issue when creating/deleting motion comment fields in the
settings [#3187]. settings [#3187].
- Fixed empty motion comment field in motion update form [#3194]. - Fixed empty motion comment field in motion update form [#3194].
- Removed server side image to base64 transformation and
added local transformation [#2705]
Core: Core:
- No reload on logoff. OpenSlides is now a full single page - No reload on logoff. OpenSlides is now a full single page

View File

@ -87,6 +87,25 @@ angular.module('OpenSlidesApp.core.pdf', [])
return '{{ballot-placeholder-to-insert-functions-here}}'; 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; return PDFLayout;
} }
]) ])

View File

@ -11,10 +11,6 @@ urlpatterns = [
views.VersionView.as_view(), views.VersionView.as_view(),
name='core_version'), name='core_version'),
url(r'^core/encode_media/$',
views.MediaEncoder.as_view(),
name="core_mediaencoding"),
url(r'^webclient/(?P<realm>site|projector)/$', url(r'^webclient/(?P<realm>site|projector)/$',
views.WebclientJavaScriptView.as_view(), views.WebclientJavaScriptView.as_view(),
name='core_webclient_javascript'), name='core_webclient_javascript'),

View File

@ -1,6 +1,4 @@
import base64
import json import json
import os
import uuid import uuid
from collections import OrderedDict from collections import OrderedDict
from operator import attrgetter from operator import attrgetter
@ -811,57 +809,3 @@ class VersionView(utils_views.APIView):
'description': get_plugin_description(plugin), 'description': get_plugin_description(plugin),
'version': get_plugin_version(plugin)}) 'version': get_plugin_version(plugin)})
return result 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

View File

@ -613,9 +613,11 @@ angular.module('OpenSlidesApp.motions.pdf', ['OpenSlidesApp.core.pdf'])
'PollContentProvider', 'PollContentProvider',
'PdfMakeBallotPaperProvider', 'PdfMakeBallotPaperProvider',
'PdfCreate', 'PdfCreate',
'PDFLayout',
'$q',
function ($http, Config, gettextCatalog, MotionChangeRecommendation, HTMLValidizer, PdfMakeConverter, function ($http, Config, gettextCatalog, MotionChangeRecommendation, HTMLValidizer, PdfMakeConverter,
MotionContentProvider, MotionCatalogContentProvider, PdfMakeDocumentProvider, PollContentProvider, MotionContentProvider, MotionCatalogContentProvider, PdfMakeDocumentProvider, PollContentProvider,
PdfMakeBallotPaperProvider, PdfCreate) { PdfMakeBallotPaperProvider, PdfCreate, PDFLayout, $q) {
return { return {
export: function (motions, params, singleMotion) { export: function (motions, params, singleMotion) {
if (!params) { if (!params) {
@ -657,9 +659,22 @@ angular.module('OpenSlidesApp.motions.pdf', ['OpenSlidesApp.core.pdf'])
image_sources = image_sources.concat(tmp_image_sources); image_sources = image_sources.concat(tmp_image_sources);
}); });
//post-request to convert the images. Async. var image_map = {};
$http.post('/core/encode_media/', JSON.stringify(image_sources)).then(function (success) { _.forEach(image_sources, function (image_source) {
var converter = PdfMakeConverter.createInstance(success.data.images); 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 = []; var motionContentProviderArray = [];
//convert all motions to motionContentProviders //convert all motions to motionContentProviders