basics for automation

This commit is contained in:
vabene1111
2021-09-15 13:07:25 +02:00
parent 71ac73ff2a
commit d6f7aade46
12 changed files with 724 additions and 22 deletions

View 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),
),
]

View File

@@ -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)

View File

@@ -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

View File

@@ -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('_', '-')

View File

@@ -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:

View File

@@ -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
}
}
)