diff --git a/cookbook/models.py b/cookbook/models.py index a3111263a..d3c494cd2 100644 --- a/cookbook/models.py +++ b/cookbook/models.py @@ -1,8 +1,14 @@ +import re + from django.contrib.auth.models import User from django.utils.translation import gettext as _ from django.db import models +def get_model_name(model): + return ('_'.join(re.findall('[A-Z][^A-Z]*', model.__name__))).lower() + + class UserPreference(models.Model): # Themes BOOTSTRAP = 'BOOTSTRAP' diff --git a/cookbook/templates/base.html b/cookbook/templates/base.html index a436e68dc..0837324eb 100644 --- a/cookbook/templates/base.html +++ b/cookbook/templates/base.html @@ -111,9 +111,9 @@ class="fas fa-database"> {% trans 'Storage Backends' %} {% trans 'Configure Sync' %} - {% trans 'Import Recipes' %} - {% trans 'Import Log' %} {% trans 'Statistics' %} diff --git a/cookbook/templates/books.html b/cookbook/templates/books.html index b1186c68c..32a95ebb8 100644 --- a/cookbook/templates/books.html +++ b/cookbook/templates/books.html @@ -10,7 +10,7 @@

{% trans 'Recipe Books' %}

diff --git a/cookbook/templates/forms/edit_internal_recipe.html b/cookbook/templates/forms/edit_internal_recipe.html index fbb718ce9..604f28a57 100644 --- a/cookbook/templates/forms/edit_internal_recipe.html +++ b/cookbook/templates/forms/edit_internal_recipe.html @@ -45,7 +45,7 @@
- {% trans 'Delete' %} {% if view_url %} {% trans 'View' %} diff --git a/cookbook/templates/generic/edit_template.html b/cookbook/templates/generic/edit_template.html index 92a75a3d3..fde67fb77 100644 --- a/cookbook/templates/generic/edit_template.html +++ b/cookbook/templates/generic/edit_template.html @@ -13,7 +13,7 @@

{% trans 'Edit' %} {{ title }}

- {% if form.Meta.model|get_class == 'Storage' %} + {% if form.Meta.model|get_class_name == 'Storage' %} {% include 'include/storage_backend_warning.html' %} {% endif %} @@ -21,7 +21,7 @@ {% csrf_token %} {{ form|crispy }} - {% trans 'Delete' %} {% if view_url %} {% trans 'View' %} diff --git a/cookbook/templates/generic/new_template.html b/cookbook/templates/generic/new_template.html index 1dc82bc2d..4f1e9fd44 100644 --- a/cookbook/templates/generic/new_template.html +++ b/cookbook/templates/generic/new_template.html @@ -13,7 +13,7 @@

{% trans 'New' %} {{ title }}

- {% if form.Meta.model|get_class == 'Storage' %} + {% if form.Meta.model|get_class_name == 'Storage' %} {% include 'include/storage_backend_warning.html' %} {% endif %} diff --git a/cookbook/templates/meal_plan.html b/cookbook/templates/meal_plan.html index 78e3ca0b0..c2956916a 100644 --- a/cookbook/templates/meal_plan.html +++ b/cookbook/templates/meal_plan.html @@ -10,7 +10,7 @@ {% block content %}

- {% trans 'Meal-Plan' %} + {% trans 'Meal-Plan' %}

@@ -55,7 +55,7 @@ {% for day_key, days_value in plan_value.days.items %} {% for mp in days_value %} - + {{ mp.recipe.name }}
{% endfor %} diff --git a/cookbook/templates/recipe_view.html b/cookbook/templates/recipe_view.html index c79df2782..6cfc12569 100644 --- a/cookbook/templates/recipe_view.html +++ b/cookbook/templates/recipe_view.html @@ -58,7 +58,7 @@ {% endif %} -
diff --git a/cookbook/templatetags/custom_tags.py b/cookbook/templatetags/custom_tags.py index d759ec409..5e8b30cd8 100644 --- a/cookbook/templatetags/custom_tags.py +++ b/cookbook/templatetags/custom_tags.py @@ -2,17 +2,29 @@ from django import template import markdown as md import bleach from bleach_whitelist import markdown_tags, markdown_attrs, all_styles, print_attrs +from django.urls import reverse from cookbook.helper.mdx_attributes import MarkdownFormatExtension +from cookbook.models import get_model_name register = template.Library() -@register.filter(name='get_class') -def get_class(value): +@register.filter() +def get_class_name(value): return value.__class__.__name__ +@register.filter() +def get_class(value): + return value.__class__ + + +@register.simple_tag +def delete_url(model, pk): + return reverse(f'delete_{get_model_name(model)}', args=[pk]) + + @register.filter() def markdown(value): tags = markdown_tags + ['pre', 'table', 'td', 'tr', 'th', 'tbody', 'style', 'thead'] diff --git a/cookbook/urls.py b/cookbook/urls.py index 066ebe74a..8b9ff4d1f 100644 --- a/cookbook/urls.py +++ b/cookbook/urls.py @@ -1,3 +1,5 @@ +from pydoc import locate + from django.urls import path from .views import * @@ -13,46 +15,16 @@ urlpatterns = [ path('view/recipe/', views.recipe_view, name='view_recipe'), - path('new/recipe/', new.RecipeCreate.as_view(), name='new_recipe'), - path('new/recipe_import//', new.create_new_external_recipe, name='new_recipe_import'), - path('new/keyword/', new.KeywordCreate.as_view(), name='new_keyword'), - path('new/storage/', new.StorageCreate.as_view(), name='new_storage'), - path('new/book/', new.RecipeBookCreate.as_view(), name='new_book'), - path('new/plan/', new.MealPlanCreate.as_view(), name='new_plan'), - - path('list/keyword', lists.keyword, name='list_keyword'), - path('list/import_log', lists.sync_log, name='list_import_log'), - path('list/import', lists.recipe_import, name='list_import'), - path('list/storage', lists.storage, name='list_storage'), - - path('edit/recipe//', edit.switch_recipe, name='edit_recipe'), path('edit/recipe/internal//', edit.internal_recipe_update, name='edit_internal_recipe'), # for internal use only path('edit/recipe/external//', edit.RecipeUpdate.as_view(), name='edit_external_recipe'), # for internal use only path('edit/recipe/convert//', edit.convert_recipe, name='edit_convert_recipe'), # for internal use only - path('edit/keyword//', edit.KeywordUpdate.as_view(), name='edit_keyword'), - path('edit/sync//', edit.SyncUpdate.as_view(), name='edit_sync'), - path('edit/import//', edit.ImportUpdate.as_view(), name='edit_import'), path('edit/storage//', edit.edit_storage, name='edit_storage'), - path('edit/comment//', edit.CommentUpdate.as_view(), name='edit_comment'), - path('edit/recipe-book//', edit.RecipeBookUpdate.as_view(), name='edit_recipe_book'), - path('edit/plan//', edit.MealPlanUpdate.as_view(), name='edit_plan'), path('edit/ingredient/', edit.edit_ingredients, name='edit_ingredient'), - path('redirect/delete///', delete.delete_redirect, name='redirect_delete'), - - path('delete/recipe//', delete.RecipeDelete.as_view(), name='delete_recipe'), path('delete/recipe-source//', delete.RecipeSourceDelete.as_view(), name='delete_recipe_source'), - path('delete/keyword//', delete.KeywordDelete.as_view(), name='delete_keyword'), - path('delete/sync//', delete.MonitorDelete.as_view(), name='delete_sync'), - path('delete/import//', delete.ImportDelete.as_view(), name='delete_import'), - path('delete/storage//', delete.StorageDelete.as_view(), name='delete_storage'), - path('delete/comment//', delete.CommentDelete.as_view(), name='delete_comment'), - path('delete/recipe-book//', delete.RecipeBookDelete.as_view(), name='delete_recipe_book'), - path('delete/recipe-book-entry//', delete.RecipeBookEntryDelete.as_view(), name='delete_recipe_book_entry'), - path('delete/plan//', delete.MealPlanDelete.as_view(), name='delete_plan'), 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'), @@ -69,3 +41,21 @@ urlpatterns = [ path('dal/ingredient/', dal.IngredientsAutocomplete.as_view(), name='dal_ingredient'), path('dal/unit/', dal.UnitAutocomplete.as_view(), name='dal_unit'), ] + +generic_models = (Recipe, RecipeImport, Storage, RecipeBook, MealPlan, SyncLog, Sync, Comment, RecipeBookEntry, Keyword) + +for m in generic_models: + py_name = get_model_name(m) + url_name = py_name.replace('_', '-') + + if c := locate(f'cookbook.views.new.{m.__name__}Create'): + urlpatterns.append(path(f'new/{url_name}/', c.as_view(), name=f'new_{py_name}')) + + if c := locate(f'cookbook.views.edit.{m.__name__}Update'): + urlpatterns.append(path(f'edit/{url_name}//', c.as_view(), name=f'edit_{py_name}')) + + if c := getattr(lists, py_name, None): + urlpatterns.append(path(f'list/{url_name}/', c, name=f'list_{py_name}')) + + if c := locate(f'cookbook.views.delete.{m.__name__}Delete'): + urlpatterns.append(path(f'delete/{url_name}//', c.as_view(), name=f'delete_{py_name}')) diff --git a/cookbook/views/delete.py b/cookbook/views/delete.py index da79ed212..288be2f6e 100644 --- a/cookbook/views/delete.py +++ b/cookbook/views/delete.py @@ -1,5 +1,4 @@ from django.contrib.auth.mixins import LoginRequiredMixin -from django.shortcuts import redirect from django.urls import reverse_lazy from django.utils.translation import gettext as _ from django.views.generic import DeleteView @@ -10,11 +9,6 @@ from cookbook.provider.dropbox import Dropbox from cookbook.provider.nextcloud import Nextcloud -# Generic Delete views -def delete_redirect(request, name, pk): - return redirect(('delete_' + name), pk) - - class RecipeDelete(LoginRequiredMixin, DeleteView): template_name = "generic/delete_template.html" model = Recipe @@ -57,13 +51,13 @@ class ImportDelete(LoginRequiredMixin, DeleteView): return context -class MonitorDelete(LoginRequiredMixin, DeleteView): +class SyncDelete(LoginRequiredMixin, DeleteView): template_name = "generic/delete_template.html" model = Sync success_url = reverse_lazy('data_sync') def get_context_data(self, **kwargs): - context = super(MonitorDelete, self).get_context_data(**kwargs) + context = super(SyncDelete, self).get_context_data(**kwargs) context['title'] = _("Monitor") return context diff --git a/cookbook/views/edit.py b/cookbook/views/edit.py index 000d079aa..cfb91541e 100644 --- a/cookbook/views/edit.py +++ b/cookbook/views/edit.py @@ -192,7 +192,7 @@ def edit_storage(request, pk): form = StorageForm(instance=pseudo_instance) return render(request, 'generic/edit_template.html', - {'form': form, 'view_url': reverse('view_recipe', args=[pk])}) + {'form': form}) class CommentUpdate(LoginRequiredMixin, UpdateView): @@ -342,4 +342,3 @@ def edit_ingredients(request): ingredients_form = IngredientMergeForm() return render(request, 'forms/ingredients.html', {'units_form': units_form, 'ingredients_form': ingredients_form}) -