mirror of
https://github.com/TandoorRecipes/recipes.git
synced 2026-01-01 04:10:06 -05:00
recipe conversion + cleanup
This commit is contained in:
18
cookbook/migrations/0010_recipe_internal.py
Normal file
18
cookbook/migrations/0010_recipe_internal.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 2.2.7 on 2019-11-15 12:55
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('cookbook', '0009_auto_20191114_1800'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='recipe',
|
||||||
|
name='internal',
|
||||||
|
field=models.BooleanField(default=False),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -61,6 +61,7 @@ class Recipe(models.Model):
|
|||||||
file_path = models.CharField(max_length=512, default="")
|
file_path = models.CharField(max_length=512, default="")
|
||||||
link = models.CharField(max_length=512, default="")
|
link = models.CharField(max_length=512, default="")
|
||||||
keywords = models.ManyToManyField(Keyword, blank=True)
|
keywords = models.ManyToManyField(Keyword, blank=True)
|
||||||
|
internal = models.BooleanField(default=False)
|
||||||
created_by = models.ForeignKey(User, on_delete=models.PROTECT)
|
created_by = models.ForeignKey(User, on_delete=models.PROTECT)
|
||||||
created_at = models.DateTimeField(auto_now_add=True)
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
updated_at = models.DateTimeField(auto_now=True)
|
updated_at = models.DateTimeField(auto_now=True)
|
||||||
|
|||||||
@@ -10,11 +10,15 @@
|
|||||||
<h3>{{ recipe.name }} <a href="{% url 'edit_recipe' recipe.pk %}"><i class="fas fa-pencil-alt"></i></a></h3>
|
<h3>{{ recipe.name }} <a href="{% url 'edit_recipe' recipe.pk %}"><i class="fas fa-pencil-alt"></i></a></h3>
|
||||||
{% if recipe.storage %}
|
{% if recipe.storage %}
|
||||||
<small>{% trans 'in' %} <a
|
<small>{% trans 'in' %} <a
|
||||||
href="{% url 'edit_storage' recipe.storage.pk %}">{{ recipe.storage.name }}</a></small><br/><br/>
|
href="{% url 'edit_storage' recipe.storage.pk %}">{{ recipe.storage.name }}</a></small><br/>
|
||||||
{% else %}
|
|
||||||
<small>{% trans 'by' %} {{ recipe.created_by.username }}</small><br/><br/>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{% if recipe.internal %}
|
||||||
|
<small>{% trans 'by' %} {{ recipe.created_by.username }}</small><br/>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
|
||||||
{% if recipe.all_tags %}
|
{% if recipe.all_tags %}
|
||||||
{{ recipe.all_tags }}
|
{{ recipe.all_tags }}
|
||||||
<br/>
|
<br/>
|
||||||
@@ -42,10 +46,32 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if recipe.storage %}
|
{% if recipe.storage %}
|
||||||
<a href='#' onClick='openRecipe({{ recipe.id }})'>{% trans 'Open recipe' %} <i
|
<a href='#' onClick='openRecipe({{ recipe.id }})'>{% trans 'View external recipe' %} <i
|
||||||
class="fas fa-external-link-alt"></i></a>
|
class="fas fa-external-link-alt"></i></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{% if not recipe.internal %}
|
||||||
|
<br/>
|
||||||
|
<br/>
|
||||||
|
<br/>
|
||||||
|
<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.
|
||||||
|
You can convert this recipe to a fancy recipe by pressing the convert button. The original file
|
||||||
|
will still be accessible.
|
||||||
|
{% endblocktrans %}.
|
||||||
|
<br/>
|
||||||
|
<br/>
|
||||||
|
<a href="{% url 'edit_convert_recipe' recipe.pk %}"
|
||||||
|
class="card-link btn btn-info">{% trans 'Convert now!' %}</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
@@ -53,21 +79,27 @@
|
|||||||
|
|
||||||
<form method="POST" class="post-form">
|
<form method="POST" class="post-form">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ form|crispy }}
|
<div class="input-group mb-3">
|
||||||
<input type="submit" value="{% trans 'Comment' %}" class="btn btn-success">
|
<textarea name="text" cols="15" rows="2" class="textarea form-control" required id="id_text">
|
||||||
|
</textarea>
|
||||||
|
<div class="input-group-append">
|
||||||
|
<input type="submit" value="{% trans 'Comment' %}" class="btn btn-success">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
{% for c in comments %}
|
{% for c in comments %}
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<small class="card-title">{{ c.updated_at }} {% trans 'by' %} {{ c.created_by.username }}</small> <br/>
|
<small class="card-title">{{ c.updated_at }} {% trans 'by' %} {{ c.created_by.username }}</small> <a
|
||||||
|
href="{% url 'edit_comment' c.pk %}"><i class="fas fa-pencil-alt"></i></a><br/>
|
||||||
{{ c.text }}
|
{{ c.text }}
|
||||||
</div>
|
</div>
|
||||||
<br/>
|
|
||||||
</div>
|
</div>
|
||||||
|
<br/>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
{% if not ingredients %}
|
{% if recipe.storage %}
|
||||||
{% include 'include/recipe_open_modal.html' %}
|
{% include 'include/recipe_open_modal.html' %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@@ -23,11 +23,13 @@ urlpatterns = [
|
|||||||
path('edit/recipe/<int:pk>/', edit.switch_recipe, name='edit_recipe'),
|
path('edit/recipe/<int:pk>/', edit.switch_recipe, name='edit_recipe'),
|
||||||
path('edit/recipe/internal/<int:pk>/', edit.internal_recipe_update, name='edit_internal_recipe'), # for internal use only
|
path('edit/recipe/internal/<int:pk>/', edit.internal_recipe_update, name='edit_internal_recipe'), # for internal use only
|
||||||
path('edit/recipe/external/<int:pk>/', edit.RecipeUpdate.as_view(), name='edit_external_recipe'), # for internal use only
|
path('edit/recipe/external/<int:pk>/', edit.RecipeUpdate.as_view(), name='edit_external_recipe'), # for internal use only
|
||||||
|
path('edit/recipe/convert/<int:pk>/', edit.convert_recipe, name='edit_convert_recipe'), # for internal use only
|
||||||
|
|
||||||
path('edit/keyword/<int:pk>/', edit.KeywordUpdate.as_view(), name='edit_keyword'),
|
path('edit/keyword/<int:pk>/', edit.KeywordUpdate.as_view(), name='edit_keyword'),
|
||||||
path('edit/sync/<int:pk>/', edit.SyncUpdate.as_view(), name='edit_sync'),
|
path('edit/sync/<int:pk>/', edit.SyncUpdate.as_view(), name='edit_sync'),
|
||||||
path('edit/import/<int:pk>/', edit.ImportUpdate.as_view(), name='edit_import'),
|
path('edit/import/<int:pk>/', edit.ImportUpdate.as_view(), name='edit_import'),
|
||||||
path('edit/storage/<int:pk>/', edit.StorageUpdate.as_view(), name='edit_storage'),
|
path('edit/storage/<int:pk>/', edit.StorageUpdate.as_view(), name='edit_storage'),
|
||||||
|
path('edit/comment/<int:pk>/', edit.CommentUpdate.as_view(), name='edit_comment'),
|
||||||
|
|
||||||
path('redirect/delete/<slug:name>/<int:pk>/', edit.delete_redirect, name='redirect_delete'),
|
path('redirect/delete/<slug:name>/<int:pk>/', edit.delete_redirect, name='redirect_delete'),
|
||||||
|
|
||||||
@@ -36,6 +38,7 @@ urlpatterns = [
|
|||||||
path('delete/sync/<int:pk>/', edit.MonitorDelete.as_view(), name='delete_sync'),
|
path('delete/sync/<int:pk>/', edit.MonitorDelete.as_view(), name='delete_sync'),
|
||||||
path('delete/import/<int:pk>/', edit.ImportDelete.as_view(), name='delete_import'),
|
path('delete/import/<int:pk>/', edit.ImportDelete.as_view(), name='delete_import'),
|
||||||
path('delete/storage/<int:pk>/', edit.StorageDelete.as_view(), name='delete_storage'),
|
path('delete/storage/<int:pk>/', edit.StorageDelete.as_view(), name='delete_storage'),
|
||||||
|
path('delete/comment/<int:pk>/', edit.CommentDelete.as_view(), name='delete_comment'),
|
||||||
|
|
||||||
path('data/sync', data.sync, name='data_sync'), # TODO move to generic "new" view
|
path('data/sync', data.sync, name='data_sync'), # TODO move to generic "new" view
|
||||||
path('data/batch/edit', data.batch_edit, name='data_batch_edit'),
|
path('data/batch/edit', data.batch_edit, name='data_batch_edit'),
|
||||||
|
|||||||
@@ -7,16 +7,25 @@ from django.urls import reverse_lazy, reverse
|
|||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
from django.views.generic import UpdateView, DeleteView
|
from django.views.generic import UpdateView, DeleteView
|
||||||
|
|
||||||
from cookbook.forms import ExternalRecipeForm, KeywordForm, StorageForm, SyncForm, InternalRecipeForm
|
from cookbook.forms import ExternalRecipeForm, KeywordForm, StorageForm, SyncForm, InternalRecipeForm, CommentForm
|
||||||
from cookbook.models import Recipe, Sync, Keyword, RecipeImport, Storage
|
from cookbook.models import Recipe, Sync, Keyword, RecipeImport, Storage, Comment
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def switch_recipe(request, pk):
|
def switch_recipe(request, pk):
|
||||||
recipe = get_object_or_404(Recipe, pk=pk)
|
recipe = get_object_or_404(Recipe, pk=pk)
|
||||||
if recipe.storage and not recipe.instructions:
|
if recipe.internal:
|
||||||
return HttpResponseRedirect(reverse('edit_external_recipe', args=[pk]))
|
return HttpResponseRedirect(reverse('edit_internal_recipe', args=[pk]))
|
||||||
else:
|
else:
|
||||||
|
return HttpResponseRedirect(reverse('edit_external_recipe', args=[pk]))
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def convert_recipe(request, pk):
|
||||||
|
recipe = get_object_or_404(Recipe, pk=pk)
|
||||||
|
if not recipe.internal:
|
||||||
|
recipe.internal = True
|
||||||
|
recipe.save()
|
||||||
return HttpResponseRedirect(reverse('edit_internal_recipe', args=[pk]))
|
return HttpResponseRedirect(reverse('edit_internal_recipe', args=[pk]))
|
||||||
|
|
||||||
|
|
||||||
@@ -93,6 +102,23 @@ class StorageUpdate(LoginRequiredMixin, UpdateView):
|
|||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
class CommentUpdate(LoginRequiredMixin, UpdateView):
|
||||||
|
template_name = "generic/edit_template.html"
|
||||||
|
model = Comment
|
||||||
|
form_class = CommentForm
|
||||||
|
|
||||||
|
# TODO add msg box
|
||||||
|
|
||||||
|
def get_success_url(self):
|
||||||
|
return reverse('edit_comment', kwargs={'pk': self.object.pk})
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super(CommentUpdate, self).get_context_data(**kwargs)
|
||||||
|
context['title'] = _("Comment")
|
||||||
|
context['view_url'] = reverse('view_recipe', args=[self.object.recipe.pk])
|
||||||
|
return context
|
||||||
|
|
||||||
|
|
||||||
class ImportUpdate(LoginRequiredMixin, UpdateView):
|
class ImportUpdate(LoginRequiredMixin, UpdateView):
|
||||||
template_name = "generic/edit_template.html"
|
template_name = "generic/edit_template.html"
|
||||||
model = RecipeImport
|
model = RecipeImport
|
||||||
@@ -191,3 +217,14 @@ class StorageDelete(LoginRequiredMixin, DeleteView):
|
|||||||
context = super(StorageDelete, self).get_context_data(**kwargs)
|
context = super(StorageDelete, self).get_context_data(**kwargs)
|
||||||
context['title'] = _("Storage Backend")
|
context['title'] = _("Storage Backend")
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
class CommentDelete(LoginRequiredMixin, DeleteView):
|
||||||
|
template_name = "generic/delete_template.html"
|
||||||
|
model = Comment
|
||||||
|
success_url = reverse_lazy('index')
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super(CommentDelete, self).get_context_data(**kwargs)
|
||||||
|
context['title'] = _("Comment")
|
||||||
|
return context
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ class RecipeCreate(LoginRequiredMixin, CreateView):
|
|||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
obj = form.save(commit=False)
|
obj = form.save(commit=False)
|
||||||
obj.created_by = self.request.user
|
obj.created_by = self.request.user
|
||||||
|
obj.internal = True
|
||||||
obj.save()
|
obj.save()
|
||||||
return HttpResponseRedirect(reverse('edit_recipe', kwargs={'pk': obj.pk}))
|
return HttpResponseRedirect(reverse('edit_recipe', kwargs={'pk': obj.pk}))
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user