WIP pdf embedding

This commit is contained in:
vabene1111
2020-02-19 16:55:13 +01:00
parent fc1cc70870
commit 88dc713683
12 changed files with 134 additions and 90 deletions

View File

@ -0,0 +1,23 @@
# Generated by Django 3.0.2 on 2020-02-19 15:05
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0025_userpreference_nav_color'),
]
operations = [
migrations.AddField(
model_name='recipe',
name='cors_link',
field=models.CharField(blank=True, max_length=1024, null=True),
),
migrations.AlterField(
model_name='recipe',
name='link',
field=models.CharField(blank=True, max_length=512, null=True),
),
]

View File

@ -84,7 +84,8 @@ class Recipe(models.Model):
storage = models.ForeignKey(Storage, on_delete=models.PROTECT, blank=True, null=True)
file_uid = models.CharField(max_length=256, default="")
file_path = models.CharField(max_length=512, default="")
link = models.CharField(max_length=512, default="")
link = models.CharField(max_length=512, null=True, blank=True)
cors_link = models.CharField(max_length=1024, null=True, blank=True)
keywords = models.ManyToManyField(Keyword, blank=True)
working_time = models.IntegerField(default=0)
waiting_time = models.IntegerField(default=0)

View File

@ -88,6 +88,16 @@ class Dropbox(Provider):
response = Dropbox.create_share_link(recipe)
return response['url']
@staticmethod
def get_cors_link(recipe):
if not recipe.link:
recipe.link = Dropbox.get_share_link(recipe)
recipe.save()
recipe.cors_link = recipe.link.replace('www.dropbox.', 'dl.dropboxusercontent.')
return recipe.cors_link
@staticmethod
def rename_file(recipe, new_name):
url = "https://api.dropboxapi.com/2/files/move_v2"

View File

@ -11,10 +11,14 @@ class Provider:
def get_share_link(recipe):
raise Exception('Method not implemented in storage provider')
@staticmethod
def get_cors_link(recipe):
raise Exception('Method not implemented in storage provider')
@staticmethod
def rename_file(recipe, new_name):
raise Exception('Method not implemented in storage provider')
@staticmethod
def delete_file(recipe, new_name):
def delete_file(recipe):
raise Exception('Method not implemented in storage provider')

View File

@ -8,8 +8,7 @@ from .models import *
class RecipeTable(tables.Table):
id = tables.LinkColumn('edit_recipe', args=[A('id')])
name = tables.TemplateColumn(
"<a href='#' onClick='openRecipe({{record.id}})'>{{record.name}}</a>")
name = tables.LinkColumn('view_recipe', args=[A('id')])
all_tags = tables.Column(
attrs={'td': {'class': 'd-none d-lg-table-cell'}, 'th': {'class': 'd-none d-lg-table-cell'}})

View File

@ -41,7 +41,7 @@
{% for r in b.recipes %}
<div class="row">
<div class="col col-md-10">
<li><a href="#" onClick='openRecipe({{ r.recipe.pk }})'>{{ r.recipe.name }}</a></li>
<li><a href="{% url 'view_recipe' r.recipe.pk %}">{{ r.recipe.name }}</a></li>
</div>
<div class="col col-md-2" style="text-align: right">
<a href="{% url 'delete_recipe_book_entry' r.pk %}"><i class="fas fa-trash-alt"></i></a>
@ -58,5 +58,4 @@
<br/>
{% endfor %}
{% include 'include/recipe_open_modal.html' %}
{% endblock %}

View File

@ -43,15 +43,12 @@
</div>
<script type="text/javascript">
function openRecipe(id, force_external = false) {
function openRecipe(id) {
var link = $('#a_recipe_open');
link.hide();
$('#div_loader').show();
var url = "{% url 'api_get_file_link' recipe_id=12345 %}".replace(/12345/, id);
if (force_external) {
url = "{% url 'api_get_external_file_link' recipe_id=12345 %}".replace(/12345/, id);
}
var url = "{% url 'api_get_external_file_link' recipe_id=12345 %}".replace(/12345/, id);
link.text("{% trans 'Open Recipe' %}");
$('#modal_recipe').modal('show');

View File

@ -63,6 +63,4 @@
</div>
{% endif %}
{% include 'include/recipe_open_modal.html' %}
{% endblock %}

View File

@ -56,7 +56,7 @@
<td>
{% for mp in days_value %}
<a href="{% url 'edit_plan' mp.pk %}"><i class="fas fa-edit"></i></a>
<a href="#" onclick="openRecipe({{ mp.recipe.id }})">{{ mp.recipe.name }}</a><br/>
<a href="{% url 'view_recipe' mp.recipe.id %}">{{ mp.recipe.name }}</a><br/>
{% endfor %}
</td>
{% endfor %}
@ -67,6 +67,4 @@
</div>
</div>
{% include 'include/recipe_open_modal.html' %}
{% endblock %}

View File

@ -134,21 +134,23 @@
{% if recipe.storage %}
<div class="row">
{% if recipe.internal %}
<a href='#' onClick='openRecipe({{ recipe.id }}, true)'
<a href='#' onClick='openRecipe({{ recipe.id }})'
class="d-print-none">{% trans 'View external recipe' %} <i class="fas fa-external-link-alt"></i></a>
{% else %}
<div class="col col-md-12" style="margin-top: 2vh">
<div class="loader" id="id_loader"></div>
<canvas id="id_pdf_canvas" class="border"></canvas>
</div>
<br/>
<br/>
<br/>
<div class="col col-md-12" style="margin-top: 2vh">
<div class="card border-info">
<div class="card-body text-info">
<h5 class="card-title">{% trans 'External recipe' %}</h5>
<p class="card-text">
{% blocktrans %}
This is an external recipe, which means you can only view it by opening the link above.
This is an external recipe, which means you can only view it by opening the link
above.
You can convert this recipe to a fancy recipe by pressing the convert button. The
original
file
@ -158,33 +160,43 @@
<br/>
<a href="{% url 'edit_convert_recipe' recipe.pk %}"
class="card-link btn btn-info">{% trans 'Convert now!' %}</a>
<a href='#' onClick='openRecipe({{ recipe.id }})'
class="d-print-none btn btn-warning">{% trans 'View external recipe' %} <i
class="fas fa-external-link-alt"></i></a>
</p>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.3.200/pdf.min.js"
integrity="sha256-J4Z8Fhj2MITUakMQatkqOVdtqodUlwHtQ/ey6fSsudE="
crossorigin="anonymous"></script>
<script type="text/javascript">
var url = "{% url 'api_get_external_file_link' recipe_id=12345 %}".replace(/12345/, {{ recipe.id }});
var url = "{% url 'api_get_cors_file_link' recipe_id=12345 %}".replace(/12345/, {{ recipe.id }});
$('#id_pdf_canvas').hide();
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState === 4 && this.status === 200) {
var url = this.responseText;
$('#id_loader').hide();
var loadingTask = pdfjsLib.getDocument(url.replace('www.dropbox.', 'dl.dropboxusercontent.'));
if (url === "None") {
// direct previews are not supported for this provider
//TODO implement something useful for providers not allowing cors links
} else {
var loadingTask = pdfjsLib.getDocument(url);
loadingTask.promise.then(function (pdf) {
console.log('PDF loaded');
$('#id_pdf_canvas').show();
// Fetch the first page
var pageNumber = 1;
pdf.getPage(pageNumber).then(function (page) {
console.log('Page loaded');
var scale = 1.5;
var viewport = page.getViewport({scale: scale*0.8});
var viewport = page.getViewport({scale: scale * 0.8});
// Prepare canvas using PDF page dimensions
var canvas = document.getElementById('id_pdf_canvas');
@ -207,11 +219,11 @@
console.error(reason);
});
}
}
};
xhttp.open("GET", url, true);
xhttp.send();
</script>
{% endif %}
</div>

View File

@ -60,8 +60,8 @@ urlpatterns = [
path('data/sync/wait', data.sync_wait, name='data_sync_wait'),
path('data/statistics', data.statistics, name='data_stats'),
path('api/get_file_link/<int:recipe_id>/', api.get_file_link, name='api_get_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/sync_all/', api.sync_all, name='api_sync'),

View File

@ -10,40 +10,43 @@ from cookbook.provider.dropbox import Dropbox
from cookbook.provider.nextcloud import Nextcloud
@login_required
def get_file_link(request, recipe_id):
recipe = Recipe.objects.get(id=recipe_id)
def update_recipe_links(recipe):
if recipe.storage.method == Storage.DROPBOX:
provider = Dropbox
elif recipe.storage.method == Storage.NEXTCLOUD:
provider = Nextcloud
else:
raise Exception('Provider not implemented')
if recipe.internal:
return HttpResponse(reverse('view_recipe', args=[recipe_id]))
if recipe.storage.method == Storage.DROPBOX: # TODO move to central location (as all provider related functions)
if recipe.link == "":
recipe.link = Dropbox.get_share_link(recipe) # TODO response validation
recipe.save()
if recipe.storage.method == Storage.NEXTCLOUD:
if recipe.link == "":
recipe.link = Nextcloud.get_share_link(recipe) # TODO response validation
recipe.save()
if not recipe.link:
recipe.link = provider.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
return HttpResponse(recipe.link)
recipe.save()
@login_required
def get_external_file_link(request, recipe_id):
recipe = Recipe.objects.get(id=recipe_id)
if recipe.storage.method == Storage.DROPBOX: # TODO move to central location (as all provider related functions)
if recipe.link == "":
recipe.link = Dropbox.get_share_link(recipe) # TODO response validation
recipe.save()
if recipe.storage.method == Storage.NEXTCLOUD:
if recipe.link == "":
recipe.link = Nextcloud.get_share_link(recipe) # TODO response validation
recipe.save()
if not recipe.link:
update_recipe_links(recipe)
return HttpResponse(recipe.link)
@login_required
def get_cors_file_link(request, recipe_id):
recipe = Recipe.objects.get(id=recipe_id)
if not recipe.cors_link:
update_recipe_links(recipe)
return HttpResponse(recipe.cors_link)
@login_required
def sync_all(request):
monitors = Sync.objects.filter(active=True)