mirror of
https://github.com/TandoorRecipes/recipes.git
synced 2026-01-01 04:10:06 -05:00
basics for automation
This commit is contained in:
35
cookbook/migrations/0152_automation.py
Normal file
35
cookbook/migrations/0152_automation.py
Normal file
@@ -0,0 +1,35 @@
|
||||
# Generated by Django 3.2.7 on 2021-09-15 10:12
|
||||
|
||||
import cookbook.models
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('cookbook', '0151_auto_20210915_1037'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Automation',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('type', models.CharField(choices=[('FOOD_ALIAS', 'Food Alias'), ('UNIT_ALIAS', 'Unit Alias'), ('KEYWORD_ALIAS', 'Keyword Alias')], max_length=128)),
|
||||
('name', models.CharField(default='', max_length=128)),
|
||||
('description', models.TextField(blank=True, null=True)),
|
||||
('param_1', models.CharField(blank=True, max_length=128, null=True)),
|
||||
('param_2', models.CharField(blank=True, max_length=128, null=True)),
|
||||
('param_3', models.CharField(blank=True, max_length=128, null=True)),
|
||||
('disabled', models.BooleanField(default=False)),
|
||||
('updated_at', models.DateTimeField(auto_now=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')),
|
||||
],
|
||||
bases=(models.Model, cookbook.models.PermissionModelMixin),
|
||||
),
|
||||
]
|
||||
@@ -865,3 +865,27 @@ class UserFile(ExportModelOperationsMixin('user_files'), models.Model, Permissio
|
||||
self.file.name = f'{uuid.uuid4()}' + pathlib.Path(self.file.name).suffix
|
||||
self.file_size_kb = round(self.file.size / 1000)
|
||||
super(UserFile, self).save(*args, **kwargs)
|
||||
|
||||
|
||||
class Automation(ExportModelOperationsMixin('automations'), models.Model, PermissionModelMixin):
|
||||
FOOD_ALIAS = 'FOOD_ALIAS'
|
||||
UNIT_ALIAS = 'UNIT_ALIAS'
|
||||
KEYWORD_ALIAS = 'KEYWORD_ALIAS'
|
||||
|
||||
type = models.CharField(max_length=128,
|
||||
choices=((FOOD_ALIAS, _('Food Alias')), (UNIT_ALIAS, _('Unit Alias')), (KEYWORD_ALIAS, _('Keyword Alias')),))
|
||||
name = models.CharField(max_length=128, default='')
|
||||
description = models.TextField(blank=True, null=True)
|
||||
|
||||
param_1 = models.CharField(max_length=128, blank=True, null=True)
|
||||
param_2 = models.CharField(max_length=128, blank=True, null=True)
|
||||
param_3 = models.CharField(max_length=128, blank=True, null=True)
|
||||
|
||||
disabled = models.BooleanField(default=False)
|
||||
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
created_by = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||
|
||||
objects = ScopedManager(space='space')
|
||||
space = models.ForeignKey(Space, on_delete=models.CASCADE)
|
||||
|
||||
@@ -17,7 +17,7 @@ from cookbook.models import (Comment, CookLog, Food, Ingredient, Keyword,
|
||||
ShareLink, ShoppingList, ShoppingListEntry,
|
||||
ShoppingListRecipe, Step, Storage, Sync, SyncLog,
|
||||
Unit, UserPreference, ViewLog, SupermarketCategory, Supermarket,
|
||||
SupermarketCategoryRelation, ImportLog, BookmarkletImport, UserFile)
|
||||
SupermarketCategoryRelation, ImportLog, BookmarkletImport, UserFile, Automation)
|
||||
from cookbook.templatetags.custom_tags import markdown
|
||||
|
||||
|
||||
@@ -683,6 +683,20 @@ class ImportLogSerializer(serializers.ModelSerializer):
|
||||
read_only_fields = ('created_by',)
|
||||
|
||||
|
||||
class AutomationSerializer(serializers.ModelSerializer):
|
||||
|
||||
def create(self, validated_data):
|
||||
validated_data['created_by'] = self.context['request'].user
|
||||
validated_data['space'] = self.context['request'].space
|
||||
return super().create(validated_data)
|
||||
|
||||
class Meta:
|
||||
model = Automation
|
||||
fields = (
|
||||
'id', 'type', 'name', 'description', 'param_1', 'param_2', 'param_3', 'disabled', 'created_by',)
|
||||
read_only_fields = ('created_by',)
|
||||
|
||||
|
||||
# CORS, REST and Scopes aren't currently working
|
||||
# Scopes are evaluating before REST has authenticated the user assiging a None space
|
||||
# I've made the change below to fix the bookmarklet, other serializers likely need a similar/better fix
|
||||
|
||||
@@ -10,7 +10,7 @@ from cookbook.helper import dal
|
||||
|
||||
from .models import (Comment, Food, InviteLink, Keyword, MealPlan, Recipe,
|
||||
RecipeBook, RecipeBookEntry, RecipeImport, ShoppingList,
|
||||
Storage, Supermarket, SupermarketCategory, Sync, SyncLog, Unit, get_model_name)
|
||||
Storage, Supermarket, SupermarketCategory, Sync, SyncLog, Unit, get_model_name, Automation)
|
||||
from .views import api, data, delete, edit, import_export, lists, new, views, telegram
|
||||
|
||||
router = routers.DefaultRouter()
|
||||
@@ -40,6 +40,7 @@ router.register(r'supermarket-category-relation', api.SupermarketCategoryRelatio
|
||||
router.register(r'import-log', api.ImportLogViewSet)
|
||||
router.register(r'bookmarklet-import', api.BookmarkletImportViewSet)
|
||||
router.register(r'user-file', api.UserFileViewSet)
|
||||
router.register(r'automation', api.AutomationViewSet)
|
||||
|
||||
urlpatterns = [
|
||||
path('', views.index, name='index'),
|
||||
@@ -177,7 +178,7 @@ for m in generic_models:
|
||||
)
|
||||
)
|
||||
|
||||
vue_models = [Food, Keyword, Unit, Supermarket, SupermarketCategory]
|
||||
vue_models = [Food, Keyword, Unit, Supermarket, SupermarketCategory, Automation]
|
||||
for m in vue_models:
|
||||
py_name = get_model_name(m)
|
||||
url_name = py_name.replace('_', '-')
|
||||
|
||||
@@ -44,7 +44,7 @@ from cookbook.models import (CookLog, Food, Ingredient, Keyword, MealPlan,
|
||||
MealType, Recipe, RecipeBook, ShoppingList,
|
||||
ShoppingListEntry, ShoppingListRecipe, Step,
|
||||
Storage, Sync, SyncLog, Unit, UserPreference,
|
||||
ViewLog, RecipeBookEntry, Supermarket, ImportLog, BookmarkletImport, SupermarketCategory, UserFile, ShareLink, SupermarketCategoryRelation)
|
||||
ViewLog, RecipeBookEntry, Supermarket, ImportLog, BookmarkletImport, SupermarketCategory, UserFile, ShareLink, SupermarketCategoryRelation, Automation)
|
||||
from cookbook.provider.dropbox import Dropbox
|
||||
from cookbook.provider.local import Local
|
||||
from cookbook.provider.nextcloud import Nextcloud
|
||||
@@ -62,7 +62,7 @@ from cookbook.serializer import (FoodSerializer, IngredientSerializer,
|
||||
UserNameSerializer, UserPreferenceSerializer,
|
||||
ViewLogSerializer, CookLogSerializer, RecipeBookEntrySerializer,
|
||||
RecipeOverviewSerializer, SupermarketSerializer, ImportLogSerializer,
|
||||
BookmarkletImportSerializer, SupermarketCategorySerializer, UserFileSerializer, SupermarketCategoryRelationSerializer)
|
||||
BookmarkletImportSerializer, SupermarketCategorySerializer, UserFileSerializer, SupermarketCategoryRelationSerializer, AutomationSerializer)
|
||||
|
||||
|
||||
class StandardFilterMixin(ViewSetMixin):
|
||||
@@ -659,6 +659,16 @@ class UserFileViewSet(viewsets.ModelViewSet, StandardFilterMixin):
|
||||
return super().get_queryset()
|
||||
|
||||
|
||||
class AutomationViewSet(viewsets.ModelViewSet, StandardFilterMixin):
|
||||
queryset = Automation.objects
|
||||
serializer_class = AutomationSerializer
|
||||
permission_classes = [CustomIsUser]
|
||||
|
||||
def get_queryset(self):
|
||||
self.queryset = self.queryset.filter(space=self.request.space).all()
|
||||
return super().get_queryset()
|
||||
|
||||
|
||||
# -------------- non django rest api views --------------------
|
||||
def get_recipe_provider(recipe):
|
||||
if recipe.storage.method == Storage.DROPBOX:
|
||||
|
||||
@@ -128,7 +128,7 @@ def food(request):
|
||||
{
|
||||
"title": _("Foods"),
|
||||
"config": {
|
||||
'model': "FOOD", # *REQUIRED* name of the model in models.js
|
||||
'model': "FOOD", # *REQUIRED* name of the model in models.js
|
||||
'recipe_param': 'foods' # *OPTIONAL* name of the listRecipes parameter if filtering on this attribute
|
||||
}
|
||||
}
|
||||
@@ -145,8 +145,8 @@ def unit(request):
|
||||
{
|
||||
"title": _("Units"),
|
||||
"config": {
|
||||
'model': "UNIT", # *REQUIRED* name of the model in models.js
|
||||
'recipe_param': 'units', # *OPTIONAL* name of the listRecipes parameter if filtering on this attribute
|
||||
'model': "UNIT", # *REQUIRED* name of the model in models.js
|
||||
'recipe_param': 'units', # *OPTIONAL* name of the listRecipes parameter if filtering on this attribute
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -162,7 +162,7 @@ def supermarket(request):
|
||||
{
|
||||
"title": _("Supermarkets"),
|
||||
"config": {
|
||||
'model': "SUPERMARKET", # *REQUIRED* name of the model in models.js
|
||||
'model': "SUPERMARKET", # *REQUIRED* name of the model in models.js
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -178,7 +178,23 @@ def supermarket_category(request):
|
||||
{
|
||||
"title": _("Shopping Categories"),
|
||||
"config": {
|
||||
'model': "SHOPPING_CATEGORY", # *REQUIRED* name of the model in models.js
|
||||
'model': "SHOPPING_CATEGORY", # *REQUIRED* name of the model in models.js
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@group_required('user')
|
||||
def automation(request):
|
||||
# recipe-param is the name of the parameters used when filtering recipes by this attribute
|
||||
# model-name is the models.js name of the model, probably ALL-CAPS
|
||||
return render(
|
||||
request,
|
||||
'generic/model_template.html',
|
||||
{
|
||||
"title": _("Automations"),
|
||||
"config": {
|
||||
'model': "AUTOMATION", # *REQUIRED* name of the model in models.js
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user