pdf display working

This commit is contained in:
vabene1111
2020-02-19 18:13:11 +01:00
parent 88dc713683
commit 0c1763b347
6 changed files with 65 additions and 53 deletions

View File

@ -1,3 +1,4 @@
import base64
import os import os
from datetime import datetime from datetime import datetime
@ -89,14 +90,14 @@ class Dropbox(Provider):
return response['url'] return response['url']
@staticmethod @staticmethod
def get_cors_link(recipe): def get_base64_file(recipe):
if not recipe.link: if not recipe.link:
recipe.link = Dropbox.get_share_link(recipe) recipe.link = Dropbox.get_share_link(recipe)
recipe.save() recipe.save()
recipe.cors_link = recipe.link.replace('www.dropbox.', 'dl.dropboxusercontent.') response = requests.get(recipe.link.replace('www.dropbox.', 'dl.dropboxusercontent.'))
return recipe.cors_link return base64.b64encode(response.content)
@staticmethod @staticmethod
def rename_file(recipe, new_name): def rename_file(recipe, new_name):

View File

@ -1,8 +1,10 @@
import base64
import os import os
import tempfile
from datetime import datetime from datetime import datetime
import webdav3.client as wc import webdav3.client as wc
import requests import requests
from io import BytesIO
from requests.auth import HTTPBasicAuth from requests.auth import HTTPBasicAuth
from cookbook.models import Recipe, RecipeImport, SyncLog from cookbook.models import Recipe, RecipeImport, SyncLog
@ -81,6 +83,20 @@ class Nextcloud(Provider):
return Nextcloud.create_share_link(recipe) return Nextcloud.create_share_link(recipe)
@staticmethod
def get_base64_file(recipe):
client = Nextcloud.get_client(recipe.storage)
tmp_file_path = tempfile.gettempdir() + '/' + recipe.name + '.pdf'
client.download_file(remote_path=recipe.file_path, local_path=tmp_file_path)
val = base64.b64encode(open(tmp_file_path, 'rb').read())
os.remove(tmp_file_path)
return val
@staticmethod @staticmethod
def rename_file(recipe, new_name): def rename_file(recipe, new_name):
client = Nextcloud.get_client(recipe.storage) client = Nextcloud.get_client(recipe.storage)

View File

@ -12,7 +12,7 @@ class Provider:
raise Exception('Method not implemented in storage provider') raise Exception('Method not implemented in storage provider')
@staticmethod @staticmethod
def get_cors_link(recipe): def get_base64_file(recipe):
raise Exception('Method not implemented in storage provider') raise Exception('Method not implemented in storage provider')
@staticmethod @staticmethod

View File

@ -141,6 +141,9 @@
<div class="col col-md-12" style="margin-top: 2vh"> <div class="col col-md-12" style="margin-top: 2vh">
<div class="loader" id="id_loader"></div> <div class="loader" id="id_loader"></div>
<canvas id="id_pdf_canvas" class="border"></canvas> <canvas id="id_pdf_canvas" class="border"></canvas>
<div class="alert alert-warning" role="alert" id="id_warning_no_preview" style="display: none">
{% trans 'Cloud not show a file preview. Maybe its not a PDF ?' %}
</div>
</div> </div>
<div class="col col-md-12" style="margin-top: 2vh"> <div class="col col-md-12" style="margin-top: 2vh">
@ -168,58 +171,53 @@
</div> </div>
</div> </div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.3.200/pdf.min.js" <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.3.200/pdf.min.js"
integrity="sha256-J4Z8Fhj2MITUakMQatkqOVdtqodUlwHtQ/ey6fSsudE=" integrity="sha256-J4Z8Fhj2MITUakMQatkqOVdtqodUlwHtQ/ey6fSsudE="
crossorigin="anonymous"></script> crossorigin="anonymous"></script>
<script type="text/javascript"> <script type="text/javascript">
var url = "{% url 'api_get_cors_file_link' recipe_id=12345 %}".replace(/12345/, {{ recipe.id }}); var url = "{% url 'api_get_recipe_file' recipe_id=12345 %}".replace(/12345/, {{ recipe.id }});
$('#id_pdf_canvas').hide(); $('#id_pdf_canvas').hide();
var xhttp = new XMLHttpRequest(); var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () { xhttp.onreadystatechange = function () {
if (this.readyState === 4 && this.status === 200) { if (this.readyState === 4 && this.status === 200) {
var url = this.responseText; var base64Pdf = atob(this.responseText);
$('#id_loader').hide(); $('#id_loader').hide();
if (url === "None") { var loadingTask = pdfjsLib.getDocument({data: base64Pdf});
// direct previews are not supported for this provider loadingTask.promise.then(function (pdf) {
//TODO implement something useful for providers not allowing cors links $('#id_pdf_canvas').show();
} else {
var loadingTask = pdfjsLib.getDocument(url);
loadingTask.promise.then(function (pdf) {
$('#id_pdf_canvas').show();
// Fetch the first page // Fetch the first page
var pageNumber = 1; var pageNumber = 1;
pdf.getPage(pageNumber).then(function (page) { pdf.getPage(pageNumber).then(function (page) {
var scale = 1.5;
var viewport = page.getViewport({scale: scale * 0.8});
// Prepare canvas using PDF page dimensions
var canvas = document.getElementById('id_pdf_canvas');
var context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
var scale = 1.5; // Render PDF page into canvas context
var viewport = page.getViewport({scale: scale * 0.8}); var renderContext = {
canvasContext: context,
// Prepare canvas using PDF page dimensions viewport: viewport
var canvas = document.getElementById('id_pdf_canvas'); };
var context = canvas.getContext('2d'); var renderTask = page.render(renderContext);
canvas.height = viewport.height; renderTask.promise.then(function () {
canvas.width = viewport.width; console.log('Page rendered');
// Render PDF page into canvas context
var renderContext = {
canvasContext: context,
viewport: viewport
};
var renderTask = page.render(renderContext);
renderTask.promise.then(function () {
console.log('Page rendered');
});
}); });
}, function (reason) {
// PDF loading error
console.error(reason);
}); });
} }, function (reason) {
// PDF loading error
console.error(reason);
$('#id_warning_no_preview').show()
});
} }
}; };
xhttp.open("GET", url, true); xhttp.open("GET", url, true);
xhttp.send(); xhttp.send();

View File

@ -61,7 +61,7 @@ urlpatterns = [
path('data/statistics', data.statistics, name='data_stats'), path('data/statistics', data.statistics, name='data_stats'),
path('api/get_external_file_link/<int:recipe_id>/', api.get_external_file_link, name='api_get_external_file_link'), path('api/get_external_file_link/<int:recipe_id>/', api.get_external_file_link, name='api_get_external_file_link'),
path('api/get_cors_file_link/<int:recipe_id>/', api.get_cors_file_link, name='api_get_cors_file_link'), path('api/get_recipe_file/<int:recipe_id>/', api.get_recipe_file, name='api_get_recipe_file'),
path('api/sync_all/', api.sync_all, name='api_sync'), path('api/sync_all/', api.sync_all, name='api_sync'),

View File

@ -1,5 +1,5 @@
from django.contrib import messages from django.contrib import messages
from django.http import HttpResponse from django.http import HttpResponse, FileResponse
from django.urls import reverse from django.urls import reverse
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
@ -10,21 +10,18 @@ from cookbook.provider.dropbox import Dropbox
from cookbook.provider.nextcloud import Nextcloud from cookbook.provider.nextcloud import Nextcloud
def update_recipe_links(recipe): def get_recipe_provider(recipe):
if recipe.storage.method == Storage.DROPBOX: if recipe.storage.method == Storage.DROPBOX:
provider = Dropbox return Dropbox
elif recipe.storage.method == Storage.NEXTCLOUD: elif recipe.storage.method == Storage.NEXTCLOUD:
provider = Nextcloud return Nextcloud
else: else:
raise Exception('Provider not implemented') raise Exception('Provider not implemented')
def update_recipe_links(recipe):
if not recipe.link: if not recipe.link:
recipe.link = provider.get_share_link(recipe) # TODO response validation in apis recipe.link = get_recipe_provider(recipe).get_share_link(recipe) # TODO response validation in apis
if not recipe.cors_link:
try:
recipe.cors_link = provider.get_cors_link(recipe)
except Exception:
pass
recipe.save() recipe.save()
@ -39,12 +36,12 @@ def get_external_file_link(request, recipe_id):
@login_required @login_required
def get_cors_file_link(request, recipe_id): def get_recipe_file(request, recipe_id):
recipe = Recipe.objects.get(id=recipe_id) recipe = Recipe.objects.get(id=recipe_id)
if not recipe.cors_link: if not recipe.cors_link:
update_recipe_links(recipe) update_recipe_links(recipe)
return HttpResponse(recipe.cors_link) return HttpResponse(get_recipe_provider(recipe).get_base64_file(recipe))
@login_required @login_required