some tweaks for new exporter
This commit is contained in:
parent
a3fa01d8d3
commit
d45e3b8e60
@ -1,3 +0,0 @@
|
||||
[Dolphin]
|
||||
Timestamp=2022,1,7,19,23,46.14
|
||||
Version=4
|
@ -152,6 +152,6 @@ REVERSE_PROXY_AUTH=0
|
||||
# Disabled by default, uncomment to enable
|
||||
# ENABLE_PDF_EXPORT=1
|
||||
|
||||
# Duration to keep the cached export file (in seconds)
|
||||
EXPORT_FILE_CACHE_DURATION=300
|
||||
# Recipe exports are cached for a certain time by default, adjust time if needed
|
||||
# EXPORT_FILE_CACHE_DURATION=600
|
||||
|
||||
|
@ -1,18 +0,0 @@
|
||||
# Generated by Django 3.2.11 on 2022-01-08 00:10
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cookbook', '0164_exportlog'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='exportlog',
|
||||
name='cache_duration',
|
||||
field=models.IntegerField(default=0),
|
||||
),
|
||||
]
|
@ -1,18 +0,0 @@
|
||||
# Generated by Django 3.2.11 on 2022-01-08 00:43
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cookbook', '0165_exportlog_cache_duration'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='exportlog',
|
||||
name='possibly_not_expired',
|
||||
field=models.BooleanField(default=True),
|
||||
),
|
||||
]
|
@ -1,4 +1,4 @@
|
||||
# Generated by Django 3.2.11 on 2022-01-07 20:29
|
||||
# Generated by Django 3.2.11 on 2022-02-03 15:03
|
||||
|
||||
import cookbook.models
|
||||
from django.conf import settings
|
||||
@ -10,7 +10,7 @@ class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('cookbook', '0163_auto_20220105_0758'),
|
||||
('cookbook', '0168_add_unit_searchfields'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
@ -23,6 +23,8 @@ class Migration(migrations.Migration):
|
||||
('msg', models.TextField(default='')),
|
||||
('total_recipes', models.IntegerField(default=0)),
|
||||
('exported_recipes', models.IntegerField(default=0)),
|
||||
('cache_duration', models.IntegerField(default=0)),
|
||||
('possibly_not_expired', models.BooleanField(default=True)),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('created_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||
('space', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cookbook.space')),
|
25
cookbook/tests/other/test_export.py
Normal file
25
cookbook/tests/other/test_export.py
Normal file
@ -0,0 +1,25 @@
|
||||
import pytest
|
||||
from django.contrib import auth
|
||||
from django.urls import reverse
|
||||
|
||||
from cookbook.forms import ImportExportBase
|
||||
from cookbook.helper.ingredient_parser import IngredientParser
|
||||
from cookbook.models import ExportLog
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def obj_1(space_1, u1_s1):
|
||||
return ExportLog.objects.create(type=ImportExportBase.DEFAULT, running=False, created_by=auth.get_user(u1_s1), space=space_1, exported_recipes=10, total_recipes=10)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("arg", [
|
||||
['a_u', 302],
|
||||
['g1_s1', 302],
|
||||
['u1_s1', 200],
|
||||
['a1_s1', 200],
|
||||
['u1_s2', 404],
|
||||
['a1_s2', 404],
|
||||
])
|
||||
def test_export_file_cache(arg, request, obj_1):
|
||||
c = request.getfixturevalue(arg[0])
|
||||
assert c.get(reverse('view_export_file', args=[obj_1.pk])).status_code == arg[1]
|
@ -73,7 +73,7 @@ urlpatterns = [
|
||||
path('abuse/<slug:token>', views.report_share_abuse, name='view_report_share_abuse'),
|
||||
|
||||
path('import/', import_export.import_recipe, name='view_import'),
|
||||
path('import-response/<int:pk>/', import_export.import_response, name='view_import_response'),\
|
||||
path('import-response/<int:pk>/', import_export.import_response, name='view_import_response'),
|
||||
path('export/', import_export.export_recipe, name='view_export'),
|
||||
path('export-response/<int:pk>/', import_export.export_response, name='view_export_response'),
|
||||
path('export-file/<int:pk>/', import_export.export_file, name='view_export_file'),
|
||||
|
@ -5,7 +5,7 @@ from django.core.cache import cache
|
||||
|
||||
from django.contrib import messages
|
||||
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
|
||||
from django.shortcuts import render
|
||||
from django.shortcuts import render, get_object_or_404
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
@ -125,7 +125,10 @@ def export_recipe(request):
|
||||
recipes = Recipe.objects.filter(space=request.space, internal=True).all()
|
||||
|
||||
integration = get_integration(request, form.cleaned_data['type'])
|
||||
|
||||
|
||||
if form.cleaned_data['type'] == ImportExportBase.PDF and not settings.ENABLE_PDF_EXPORT:
|
||||
return JsonResponse({'error': _('The PDF Exporter is not enabled on this instance as it is still in an experimental state.')})
|
||||
|
||||
el = ExportLog.objects.create(type=form.cleaned_data['type'], created_by=request.user, space=request.space)
|
||||
|
||||
t = threading.Thread(target=integration.do_export, args=[recipes, el])
|
||||
@ -141,7 +144,6 @@ def export_recipe(request):
|
||||
},
|
||||
status=400
|
||||
)
|
||||
|
||||
else:
|
||||
pk = ''
|
||||
recipe = request.GET.get('r')
|
||||
@ -156,6 +158,7 @@ def export_recipe(request):
|
||||
def import_response(request, pk):
|
||||
return render(request, 'import_response.html', {'pk': pk})
|
||||
|
||||
|
||||
@group_required('user')
|
||||
def export_response(request, pk):
|
||||
return render(request, 'export_response.html', {'pk': pk})
|
||||
@ -163,16 +166,15 @@ def export_response(request, pk):
|
||||
|
||||
@group_required('user')
|
||||
def export_file(request, pk):
|
||||
|
||||
cacheData = cache.get('export_file_'+str(pk))
|
||||
el = get_object_or_404(ExportLog, pk=pk, space=request.space)
|
||||
|
||||
cacheData = cache.get(f'export_file_{el.pk}')
|
||||
|
||||
if cacheData is None:
|
||||
el = ExportLog.objects.get(pk=pk)
|
||||
el.possibly_not_expired = False;
|
||||
el.possibly_not_expired = False
|
||||
el.save()
|
||||
return render(request, 'export_response.html', {'pk': pk})
|
||||
|
||||
response = HttpResponse(cacheData['file'], content_type='application/force-download')
|
||||
response['Content-Disposition'] = 'attachment; filename="'+cacheData['filename']+'"'
|
||||
response['Content-Disposition'] = 'attachment; filename="' + cacheData['filename'] + '"'
|
||||
return response
|
||||
|
||||
|
@ -21,26 +21,26 @@ if your favorite one is missing.
|
||||
Overview of the capabilities of the different integrations.
|
||||
|
||||
| Integration | Import | Export | Images |
|
||||
|--------------------| ------ | ------ | ------ |
|
||||
| Default | ✔️ | ✔️ | ✔️ |
|
||||
| Nextcloud | ✔️ | ⌚ | ✔️ |
|
||||
| Mealie | ✔️ | ⌚ | ✔️ |
|
||||
| Chowdown | ✔️ | ⌚ | ✔️ |
|
||||
| Safron | ✔️ | ✔ | ❌ |
|
||||
| Paprika | ✔️ | ⌚ | ✔️ |
|
||||
| ChefTap | ✔️ | ❌ | ❌ |
|
||||
| Pepperplate | ✔️ | ⌚ | ❌ |
|
||||
| RecipeSage | ✔️ | ✔️ | ✔️ |
|
||||
| Domestica | ✔️ | ⌚ | ✔️ |
|
||||
| MealMaster | ✔️ | ❌ | ❌ |
|
||||
| RezKonv | ✔️ | ❌ | ❌ |
|
||||
| OpenEats | ✔️ | ❌ | ⌚ |
|
||||
| Plantoeat | ✔️ | ❌ | ✔ |
|
||||
| CookBookApp | ✔️ | ⌚ | ✔️ |
|
||||
| CopyMeThat | ✔️ | ❌ | ✔️ |
|
||||
| PDF (experimental) | ⌚️ | ✔ | ✔️ |
|
||||
|--------------------| ------ | -- | ------ |
|
||||
| Default | ✔️ | ✔️ | ✔️ |
|
||||
| Nextcloud | ✔️ | ⌚ | ✔️ |
|
||||
| Mealie | ✔️ | ⌚ | ✔️ |
|
||||
| Chowdown | ✔️ | ⌚ | ✔️ |
|
||||
| Safron | ✔️ | ✔️ | ❌ |
|
||||
| Paprika | ✔️ | ⌚ | ✔️ |
|
||||
| ChefTap | ✔️ | ❌ | ❌ |
|
||||
| Pepperplate | ✔️ | ⌚ | ❌ |
|
||||
| RecipeSage | ✔️ | ✔️ | ✔️ |
|
||||
| Domestica | ✔️ | ⌚ | ✔️ |
|
||||
| MealMaster | ✔️ | ❌ | ❌ |
|
||||
| RezKonv | ✔️ | ❌ | ❌ |
|
||||
| OpenEats | ✔️ | ❌ | ⌚ |
|
||||
| Plantoeat | ✔️ | ❌ | ✔ |
|
||||
| CookBookApp | ✔️ | ⌚ | ✔️ |
|
||||
| CopyMeThat | ✔️ | ❌ | ✔️ |
|
||||
| PDF (experimental) | ⌚️ | ✔️ | ✔️ |
|
||||
|
||||
✔ = implemented, ❌ = not implemented and not possible/planned, ⌚ = not yet implemented
|
||||
✔️ = implemented, ❌ = not implemented and not possible/planned, ⌚ = not yet implemented
|
||||
|
||||
## Default
|
||||
The default integration is the built in (and preferred) way to import and export recipes.
|
||||
|
@ -9,24 +9,9 @@
|
||||
<!-- TODO get option dynamicaly -->
|
||||
<select class="form-control" v-model="recipe_app">
|
||||
<option value="DEFAULT">Default</option>
|
||||
<option value="PAPRIKA">Paprika</option>
|
||||
<option value="NEXTCLOUD">Nextcloud Cookbook</option>
|
||||
<option value="MEALIE">Mealie</option>
|
||||
<option value="CHOWDOWN">Chowdown</option>
|
||||
<option value="SAFFRON">Saffron</option>
|
||||
<option value="CHEFTAP">ChefTap</option>
|
||||
<option value="PEPPERPLATE">Pepperplate</option>
|
||||
<option value="RECETTETEK">RecetteTek</option>
|
||||
<option value="RECIPESAGE">Recipe Sage</option>
|
||||
<option value="DOMESTICA">Domestica</option>
|
||||
<option value="MEALMASTER">MealMaster</option>
|
||||
<option value="REZKONV">RezKonv</option>
|
||||
<option value="OPENEATS">Openeats</option>
|
||||
<option value="RECIPEKEEPER">Recipe Keeper</option>
|
||||
<option value="PLANTOEAT">Plantoeat</option>
|
||||
<option value="COOKBOOKAPP">CookBookApp</option>
|
||||
<option value="COPYMETHAT">CopyMeThat</option>
|
||||
<option value="PDF">PDF</option>
|
||||
<option value="PDF">PDF (experimental)</option>
|
||||
</select>
|
||||
|
||||
<br/>
|
||||
@ -53,8 +38,6 @@
|
||||
@search-change="searchRecipes">
|
||||
</multiselect>
|
||||
|
||||
|
||||
|
||||
<br/>
|
||||
<button @click="exportRecipe()" class="btn btn-primary shadow-none"><i class="fas fa-file-export"></i> {{ $t('Export') }}
|
||||
</button>
|
||||
@ -164,14 +147,17 @@ export default {
|
||||
|
||||
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
|
||||
axios.post(resolveDjangoUrl('view_export',), formData).then((response) => {
|
||||
|
||||
window.location.href = resolveDjangoUrl('view_export_response', response.data['export_id'])
|
||||
if (response.data['error'] !== undefined){
|
||||
makeToast(this.$t("Error"), response.data['error'],"warning")
|
||||
}else{
|
||||
window.location.href = resolveDjangoUrl('view_export_response', response.data['export_id'])
|
||||
}
|
||||
|
||||
}).catch((err) => {
|
||||
this.error = err.data
|
||||
this.loading = false
|
||||
console.log(err)
|
||||
makeToast(this.$t("Error"), this.$t("There was an error loading a resource!"), "danger")
|
||||
makeToast(this.$t("Error"), this.$t("There was an error loading a resource!"), "warning")
|
||||
})
|
||||
},
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user