diff --git a/cookbook/admin.py b/cookbook/admin.py
index 3429e63d..64a03173 100644
--- a/cookbook/admin.py
+++ b/cookbook/admin.py
@@ -16,7 +16,7 @@ from .models import (BookmarkletImport, Comment, CookLog, Food, ImportLog, Ingre
ShoppingList, ShoppingListEntry, ShoppingListRecipe, Space, Step, Storage,
Supermarket, SupermarketCategory, SupermarketCategoryRelation, Sync, SyncLog,
TelegramBot, Unit, UnitConversion, UserFile, UserPreference, UserSpace,
- ViewLog, HomeAssistantConfig)
+ ViewLog, HomeAssistantConfig, ExampleConfig)
class CustomUserAdmin(UserAdmin):
@@ -103,6 +103,14 @@ class HomeAssistantConfigAdmin(admin.ModelAdmin):
admin.site.register(HomeAssistantConfig, HomeAssistantConfigAdmin)
+class ExampleConfigAdmin(admin.ModelAdmin):
+ list_display = ('id', 'name', 'enabled', 'feed_url')
+ search_fields = ('name',)
+
+
+admin.site.register(ExampleConfig, ExampleConfigAdmin)
+
+
class SyncAdmin(admin.ModelAdmin):
list_display = ('storage', 'path', 'active', 'last_checked')
search_fields = ('storage__name', 'path')
diff --git a/cookbook/connectors/connector_manager.py b/cookbook/connectors/connector_manager.py
index 39919597..178c8efb 100644
--- a/cookbook/connectors/connector_manager.py
+++ b/cookbook/connectors/connector_manager.py
@@ -12,14 +12,15 @@ from typing import List, Any, Dict, Optional
from django_scopes import scope
from cookbook.connectors.connector import Connector
+from cookbook.connectors.example import Example
from cookbook.connectors.homeassistant import HomeAssistant
-from cookbook.models import ShoppingListEntry, Recipe, MealPlan, Space, HomeAssistantConfig, ConnectorConfig
+from cookbook.models import ShoppingListEntry, Recipe, MealPlan, Space, HomeAssistantConfig, ExampleConfig
multiprocessing.set_start_method('fork') # https://code.djangoproject.com/ticket/31169
QUEUE_MAX_SIZE = 25
REGISTERED_CLASSES: UnionType = ShoppingListEntry | Recipe | MealPlan
-CONNECTOR_UPDATE_CLASSES: UnionType = HomeAssistantConfig | ConnectorConfig
+CONNECTOR_UPDATE_CLASSES: UnionType = HomeAssistantConfig | ExampleConfig
class ActionType(Enum):
@@ -97,7 +98,10 @@ class ConnectorManager:
loop.run_until_complete(close_connectors(connectors))
with scope(space=space):
- connectors: List[Connector] = [HomeAssistant(config) for config in space.homeassistantconfig_set.all() if config.enabled]
+ connectors: List[Connector] = [
+ *(HomeAssistant(config) for config in space.homeassistantconfig_set.all() if config.enabled),
+ *(Example(config) for config in space.exampleconfig_set.all() if config.enabled)
+ ]
_connectors[space.name] = connectors
if len(connectors) == 0 or refresh_connector_cache:
diff --git a/cookbook/connectors/example.py b/cookbook/connectors/example.py
new file mode 100644
index 00000000..ce55f476
--- /dev/null
+++ b/cookbook/connectors/example.py
@@ -0,0 +1,27 @@
+from cookbook.connectors.connector import Connector
+from cookbook.models import ExampleConfig, Space, ShoppingListEntry
+
+
+class Example(Connector):
+ _config: ExampleConfig
+
+ def __init__(self, config: ExampleConfig):
+ self._config = config
+
+ async def on_shopping_list_entry_created(self, space: Space, shopping_list_entry: ShoppingListEntry) -> None:
+ if not self._config.on_shopping_list_entry_created_enabled:
+ return
+ pass
+
+ async def on_shopping_list_entry_updated(self, space: Space, shopping_list_entry: ShoppingListEntry) -> None:
+ if not self._config.on_shopping_list_entry_updated_enabled:
+ return
+ pass
+
+ async def on_shopping_list_entry_deleted(self, space: Space, shopping_list_entry: ShoppingListEntry) -> None:
+ if not self._config.on_shopping_list_entry_deleted_enabled:
+ return
+ pass
+
+ async def close(self) -> None:
+ pass
diff --git a/cookbook/forms.py b/cookbook/forms.py
index dce4da57..18867958 100644
--- a/cookbook/forms.py
+++ b/cookbook/forms.py
@@ -10,7 +10,7 @@ from django_scopes.forms import SafeModelChoiceField, SafeModelMultipleChoiceFie
from hcaptcha.fields import hCaptchaField
from .models import (Comment, Food, InviteLink, Keyword, Recipe, RecipeBook, RecipeBookEntry,
- SearchPreference, Space, Storage, Sync, User, UserPreference, HomeAssistantConfig)
+ SearchPreference, Space, Storage, Sync, User, UserPreference, HomeAssistantConfig, ExampleConfig)
class SelectWidget(widgets.Select):
@@ -188,12 +188,35 @@ class StorageForm(forms.ModelForm):
}
-class HomeAssistantConfigForm(forms.ModelForm):
- token = forms.CharField(
- widget=forms.TextInput(
- attrs={'autocomplete': 'new-password', 'type': 'password'}
- ),
- required=True,
+class ConnectorConfigForm(forms.ModelForm):
+ enabled = forms.BooleanField(
+ help_text="Is the connector enabled",
+ required=False,
+ )
+
+ on_shopping_list_entry_created_enabled = forms.BooleanField(
+ help_text="Enable action for ShoppingListEntry created events",
+ required=False,
+ )
+
+ on_shopping_list_entry_updated_enabled = forms.BooleanField(
+ help_text="Enable action for ShoppingListEntry updated events",
+ required=False,
+ )
+
+ on_shopping_list_entry_deleted_enabled = forms.BooleanField(
+ help_text="Enable action for ShoppingListEntry deleted events",
+ required=False,
+ )
+
+ class Meta:
+ fields = ('name', 'enabled', 'on_shopping_list_entry_created_enabled', 'on_shopping_list_entry_updated_enabled', 'on_shopping_list_entry_deleted_enabled')
+
+
+class HomeAssistantConfigForm(ConnectorConfigForm):
+ update_token = forms.CharField(
+ widget=forms.TextInput(attrs={'autocomplete': 'update-token', 'type': 'password'}),
+ required=False,
help_text=_('Long Lived Access Token for your HomeAssistant instance')
)
@@ -202,11 +225,6 @@ class HomeAssistantConfigForm(forms.ModelForm):
help_text=_('Something like http://homeassistant.local:8123/api'),
)
- enabled = forms.BooleanField(
- help_text="Is the HomeAssistantConnector enabled",
- required=False,
- )
-
on_shopping_list_entry_created_enabled = forms.BooleanField(
help_text="Enable syncing ShoppingListEntry to Homeassistant Todo List -- Warning: Might have negative performance impact",
required=False,
@@ -224,15 +242,24 @@ class HomeAssistantConfigForm(forms.ModelForm):
class Meta:
model = HomeAssistantConfig
- fields = (
- 'name', 'url', 'token', 'todo_entity', 'enabled', 'on_shopping_list_entry_created_enabled', 'on_shopping_list_entry_updated_enabled',
- 'on_shopping_list_entry_deleted_enabled')
+
+ fields = ConnectorConfigForm.Meta.fields + ('url', 'todo_entity')
help_texts = {
'url': _('http://homeassistant.local:8123/api for example'),
}
+class ExampleConfigForm(ConnectorConfigForm):
+ feed_url = forms.URLField(
+ required=False,
+ )
+
+ class Meta:
+ model = ExampleConfig
+ fields = ConnectorConfigForm.Meta.fields + ('feed_url',)
+
+
# TODO: Deprecate
class RecipeBookEntryForm(forms.ModelForm):
prefix = 'bookmark'
diff --git a/cookbook/migrations/0208_homeassistantconfig.py b/cookbook/migrations/0208_homeassistantconfig_exampleconfig.py
similarity index 58%
rename from cookbook/migrations/0208_homeassistantconfig.py
rename to cookbook/migrations/0208_homeassistantconfig_exampleconfig.py
index f21ff06a..789094c1 100644
--- a/cookbook/migrations/0208_homeassistantconfig.py
+++ b/cookbook/migrations/0208_homeassistantconfig_exampleconfig.py
@@ -1,4 +1,4 @@
-# Generated by Django 4.2.7 on 2024-01-12 21:01
+# Generated by Django 4.2.7 on 2024-01-14 16:00
import cookbook.models
from django.conf import settings
@@ -35,4 +35,22 @@ class Migration(migrations.Migration):
},
bases=(models.Model, cookbook.models.PermissionModelMixin),
),
+ migrations.CreateModel(
+ name='ExampleConfig',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(max_length=128, validators=[django.core.validators.MinLengthValidator(1)])),
+ ('enabled', models.BooleanField(default=True, help_text='Is Connector Enabled')),
+ ('on_shopping_list_entry_created_enabled', models.BooleanField(default=False)),
+ ('on_shopping_list_entry_updated_enabled', models.BooleanField(default=False)),
+ ('on_shopping_list_entry_deleted_enabled', models.BooleanField(default=False)),
+ ('feed_url', models.URLField(blank=True)),
+ ('created_by', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)),
+ ('space', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cookbook.space')),
+ ],
+ options={
+ 'abstract': False,
+ },
+ bases=(models.Model, cookbook.models.PermissionModelMixin),
+ ),
]
diff --git a/cookbook/models.py b/cookbook/models.py
index 9d6b9c5a..a41dc37f 100644
--- a/cookbook/models.py
+++ b/cookbook/models.py
@@ -340,6 +340,7 @@ class Space(ExportModelOperationsMixin('space'), models.Model):
Sync.objects.filter(space=self).delete()
Storage.objects.filter(space=self).delete()
HomeAssistantConfig.objects.filter(space=self).delete()
+ ExampleConfig.objects.filter(space=self).delete()
ShoppingListEntry.objects.filter(shoppinglist__space=self).delete()
ShoppingListRecipe.objects.filter(shoppinglist__space=self).delete()
@@ -387,6 +388,10 @@ class HomeAssistantConfig(ConnectorConfig):
todo_entity = models.CharField(max_length=128, default='todo.shopping_list')
+class ExampleConfig(ConnectorConfig):
+ feed_url = models.URLField(blank=True)
+
+
class UserPreference(models.Model, PermissionModelMixin):
# Themes
BOOTSTRAP = 'BOOTSTRAP'
diff --git a/cookbook/tables.py b/cookbook/tables.py
index 4f49690c..ba14fbbe 100644
--- a/cookbook/tables.py
+++ b/cookbook/tables.py
@@ -1,9 +1,14 @@
+from typing import Any, Dict
+
import django_tables2 as tables
from django.utils.html import format_html
from django.utils.translation import gettext as _
+from django.views.generic import TemplateView
+from django_tables2 import MultiTableMixin
from django_tables2.utils import A
-from .models import CookLog, InviteLink, RecipeImport, Storage, Sync, SyncLog, ViewLog, HomeAssistantConfig
+from .helper.permission_helper import GroupRequiredMixin
+from .models import CookLog, InviteLink, RecipeImport, Storage, Sync, SyncLog, ViewLog, HomeAssistantConfig, ExampleConfig
class StorageTable(tables.Table):
@@ -15,6 +20,16 @@ class StorageTable(tables.Table):
fields = ('id', 'name', 'method')
+class ExampleConfigTable(tables.Table):
+ id = tables.LinkColumn('edit_example_config', args=[A('id')])
+
+ class Meta:
+ model = ExampleConfig
+ template_name = 'generic/table_template.html'
+ fields = ('id', 'name', 'enabled', 'feed_url')
+ attrs = {'table_name': "Example Configs", 'create_url': 'new_example_config'}
+
+
class HomeAssistantConfigTable(tables.Table):
id = tables.LinkColumn('edit_home_assistant_config', args=[A('id')])
@@ -22,6 +37,30 @@ class HomeAssistantConfigTable(tables.Table):
model = HomeAssistantConfig
template_name = 'generic/table_template.html'
fields = ('id', 'name', 'enabled', 'url')
+ attrs = {'table_name': "HomeAssistant Configs", 'create_url': 'new_home_assistant_config'}
+
+
+class ConnectorConfigTable(GroupRequiredMixin, MultiTableMixin, TemplateView):
+ groups_required = ['admin']
+ template_name = "list_connectors.html"
+
+ table_pagination = {
+ "per_page": 25
+ }
+
+ def get_context_data(self, **kwargs: Any) -> Dict[str, Any]:
+ kwargs = super().get_context_data(**kwargs)
+ kwargs['title'] = _("Connectors")
+ return kwargs
+
+ def get_tables(self):
+ example_configs = ExampleConfig.objects.filter(space=self.request.space).all()
+ home_assistant_configs = HomeAssistantConfig.objects.filter(space=self.request.space).all()
+
+ return [
+ ExampleConfigTable(example_configs),
+ HomeAssistantConfigTable(home_assistant_configs)
+ ]
class ImportLogTable(tables.Table):
diff --git a/cookbook/templates/base.html b/cookbook/templates/base.html
index d9e2eda1..7fbb14db 100644
--- a/cookbook/templates/base.html
+++ b/cookbook/templates/base.html
@@ -336,7 +336,7 @@
class="fas fa-server fa-fw"> {% trans 'Space Settings' %}
{% endif %}
{% if request.user == request.space.created_by or user.is_superuser %}
- {% trans 'External Connectors' %}
{% endif %}
{% if user.is_superuser %}
diff --git a/cookbook/templates/list_connectors.html b/cookbook/templates/list_connectors.html
new file mode 100644
index 00000000..283f7c31
--- /dev/null
+++ b/cookbook/templates/list_connectors.html
@@ -0,0 +1,55 @@
+{% extends "base.html" %}
+{% load crispy_forms_tags %}
+{% load i18n %}
+{% load django_tables2 %}
+
+{% block title %}{% trans 'List' %}{% endblock %}
+
+
+{% block content %}
+
+{% if request.resolver_match.url_name in 'list_storage,list_recipe_import,list_sync_log' %}
+
+{% endif %}
+
+
+
+ {{ title }} {% trans 'List' %}
+
+
+ {% if filter %}
+
+
+
+ {% endif %}
+
+ {% if import_btn %}
+
{% trans 'Import all' %}
+
+
+ {% endif %}
+
+ {% for table in tables %}
+
+ {{ table.attrs.table_name }} {% trans 'List' %}
+ {% if table.attrs.create_url %}
+
+ {% endif %}
+
+
+
+ {% render_table table %}
+ {% endfor %}
+
+
+
+{% endblock content %}
\ No newline at end of file
diff --git a/cookbook/urls.py b/cookbook/urls.py
index 96735037..e85cfbaf 100644
--- a/cookbook/urls.py
+++ b/cookbook/urls.py
@@ -12,7 +12,8 @@ from recipes.settings import DEBUG, PLUGINS
from .models import (Automation, Comment, CustomFilter, Food, InviteLink, Keyword, PropertyType,
Recipe, RecipeBook, RecipeBookEntry, RecipeImport, ShoppingList, Space, Step,
Storage, Supermarket, SupermarketCategory, Sync, SyncLog, Unit, UnitConversion,
- UserFile, UserSpace, get_model_name, HomeAssistantConfig)
+ UserFile, UserSpace, get_model_name, HomeAssistantConfig, ExampleConfig)
+from .tables import ConnectorConfigTable
from .views import api, data, delete, edit, import_export, lists, new, telegram, views
from .views.api import CustomAuthToken, ImportOpenData
@@ -115,7 +116,7 @@ urlpatterns = [
path('edit/recipe/convert//', edit.convert_recipe, name='edit_convert_recipe'),
path('edit/storage//', edit.edit_storage, name='edit_storage'),
- path('edit/home-assistant-config//', edit.edit_home_assistant_config, name='edit_home_assistant_config'),
+ path('list/connectors', ConnectorConfigTable.as_view(), name='list_connectors'),
path('delete/recipe-source//', delete.delete_recipe_source, name='delete_recipe_source'),
@@ -168,7 +169,7 @@ urlpatterns = [
]
generic_models = (
- Recipe, RecipeImport, Storage, HomeAssistantConfig, RecipeBook, SyncLog, Sync,
+ Recipe, RecipeImport, Storage, HomeAssistantConfig, ExampleConfig, RecipeBook, SyncLog, Sync,
Comment, RecipeBookEntry, ShoppingList, InviteLink, UserSpace, Space
)
diff --git a/cookbook/views/delete.py b/cookbook/views/delete.py
index b6cf857b..bbdc98ee 100644
--- a/cookbook/views/delete.py
+++ b/cookbook/views/delete.py
@@ -9,7 +9,7 @@ from django.views.generic import DeleteView
from cookbook.helper.permission_helper import GroupRequiredMixin, OwnerRequiredMixin, group_required
from cookbook.models import (Comment, InviteLink, MealPlan, Recipe, RecipeBook, RecipeBookEntry,
- RecipeImport, Space, Storage, Sync, UserSpace, HomeAssistantConfig)
+ RecipeImport, Space, Storage, Sync, UserSpace, HomeAssistantConfig, ExampleConfig)
from cookbook.provider.dropbox import Dropbox
from cookbook.provider.local import Local
from cookbook.provider.nextcloud import Nextcloud
@@ -126,23 +126,24 @@ class HomeAssistantConfigDelete(GroupRequiredMixin, DeleteView):
groups_required = ['admin']
template_name = "generic/delete_template.html"
model = HomeAssistantConfig
- success_url = reverse_lazy('list_storage')
+ success_url = reverse_lazy('list_connectors')
def get_context_data(self, **kwargs):
- context = super(HomeAssistantConfigDelete, self).get_context_data(**kwargs)
+ context = super().get_context_data(**kwargs)
context['title'] = _("HomeAssistant Config Backend")
return context
- def post(self, request, *args, **kwargs):
- try:
- return self.delete(request, *args, **kwargs)
- except ProtectedError:
- messages.add_message(
- request,
- messages.WARNING,
- _('Could not delete this storage backend as it is used in at least one monitor.') # noqa: E501
- )
- return HttpResponseRedirect(reverse('list_storage'))
+
+class ExampleConfigDelete(GroupRequiredMixin, DeleteView):
+ groups_required = ['admin']
+ template_name = "generic/delete_template.html"
+ model = ExampleConfig
+ success_url = reverse_lazy('list_connectors')
+
+ def get_context_data(self, **kwargs):
+ context = super().get_context_data(**kwargs)
+ context['title'] = _("Example Config Backend")
+ return context
class CommentDelete(OwnerRequiredMixin, DeleteView):
diff --git a/cookbook/views/edit.py b/cookbook/views/edit.py
index deb9654b..2f99216b 100644
--- a/cookbook/views/edit.py
+++ b/cookbook/views/edit.py
@@ -9,10 +9,10 @@ from django.utils.translation import gettext as _
from django.views.generic import UpdateView
from django.views.generic.edit import FormMixin
-from cookbook.forms import CommentForm, ExternalRecipeForm, StorageForm, SyncForm, HomeAssistantConfigForm
+from cookbook.forms import CommentForm, ExternalRecipeForm, StorageForm, SyncForm, HomeAssistantConfigForm, ExampleConfigForm
from cookbook.helper.permission_helper import (GroupRequiredMixin, OwnerRequiredMixin,
above_space_limit, group_required)
-from cookbook.models import Comment, Recipe, RecipeImport, Storage, Sync, HomeAssistantConfig
+from cookbook.models import Comment, Recipe, RecipeImport, Storage, Sync, HomeAssistantConfig, ExampleConfig
from cookbook.provider.dropbox import Dropbox
from cookbook.provider.local import Local
from cookbook.provider.nextcloud import Nextcloud
@@ -128,46 +128,49 @@ def edit_storage(request, pk):
)
-@group_required('admin')
-def edit_home_assistant_config(request, pk):
- instance: HomeAssistantConfig = get_object_or_404(HomeAssistantConfig, pk=pk, space=request.space)
+class HomeAssistantConfigUpdate(GroupRequiredMixin, UpdateView):
+ groups_required = ['admin']
+ template_name = "generic/edit_template.html"
+ model = HomeAssistantConfig
+ form_class = HomeAssistantConfigForm
- if not (instance.created_by == request.user or request.user.is_superuser):
- messages.add_message(request, messages.ERROR, _('You cannot edit this homeassistant config!'))
- return HttpResponseRedirect(reverse('edit_home_assistant_config'))
+ def get_form_kwargs(self):
+ kwargs = super().get_form_kwargs()
+ kwargs['initial']['update_token'] = VALUE_NOT_CHANGED
+ return kwargs
- if request.space.demo or settings.HOSTED:
- messages.add_message(request, messages.ERROR, _('This feature is not yet available in the hosted version of tandoor!'))
- return redirect('index')
+ def form_valid(self, form):
+ if form.cleaned_data['update_token'] != VALUE_NOT_CHANGED and form.cleaned_data['update_token'] != "":
+ form.instance.token = form.cleaned_data['update_token']
+ messages.add_message(self.request, messages.SUCCESS, _('Config saved!'))
+ return super(HomeAssistantConfigUpdate, self).form_valid(form)
- if request.method == "POST":
- form = HomeAssistantConfigForm(request.POST, instance=copy.deepcopy(instance))
- if form.is_valid():
- instance.name = form.cleaned_data['name']
- instance.url = form.cleaned_data['url']
- instance.todo_entity = form.cleaned_data['todo_entity']
- instance.enabled = form.cleaned_data['enabled']
- instance.on_shopping_list_entry_created_enabled = form.cleaned_data['on_shopping_list_entry_created_enabled']
- instance.on_shopping_list_entry_updated_enabled = form.cleaned_data['on_shopping_list_entry_updated_enabled']
- instance.on_shopping_list_entry_deleted_enabled = form.cleaned_data['on_shopping_list_entry_deleted_enabled']
+ def get_success_url(self):
+ return reverse('edit_home_assistant_config', kwargs={'pk': self.object.pk})
- if form.cleaned_data['token'] != VALUE_NOT_CHANGED:
- instance.token = form.cleaned_data['token']
+ def get_context_data(self, **kwargs):
+ context = super().get_context_data(**kwargs)
+ context['title'] = _("HomeAssistantConfig")
+ return context
- instance.save()
- messages.add_message(request, messages.SUCCESS, _('HomeAssistant config saved!'))
- else:
- messages.add_message(request, messages.ERROR, _('There was an error updating this config!'))
- else:
- instance.token = VALUE_NOT_CHANGED
- form = HomeAssistantConfigForm(instance=instance)
+class ExampleConfigUpdate(GroupRequiredMixin, UpdateView):
+ groups_required = ['admin']
+ template_name = "generic/edit_template.html"
+ model = ExampleConfig
+ form_class = ExampleConfigForm
- return render(
- request,
- 'generic/edit_template.html',
- {'form': form, 'title': _('HomeAssistantConfig')}
- )
+ def form_valid(self, form):
+ messages.add_message(self.request, messages.SUCCESS, _('Config saved!'))
+ return super().form_valid(form)
+
+ def get_success_url(self):
+ return reverse('edit_example_config', kwargs={'pk': self.object.pk})
+
+ def get_context_data(self, **kwargs):
+ context = super().get_context_data(**kwargs)
+ context['title'] = _("ExampleConfig")
+ return context
class CommentUpdate(OwnerRequiredMixin, UpdateView):
diff --git a/cookbook/views/lists.py b/cookbook/views/lists.py
index 20dbb73c..ed43c143 100644
--- a/cookbook/views/lists.py
+++ b/cookbook/views/lists.py
@@ -6,8 +6,8 @@ from django.utils.translation import gettext as _
from django_tables2 import RequestConfig
from cookbook.helper.permission_helper import group_required
-from cookbook.models import InviteLink, RecipeImport, Storage, SyncLog, UserFile, HomeAssistantConfig
-from cookbook.tables import ImportLogTable, InviteLinkTable, RecipeImportTable, StorageTable, HomeAssistantConfigTable
+from cookbook.models import InviteLink, RecipeImport, Storage, SyncLog, UserFile
+from cookbook.tables import ImportLogTable, InviteLinkTable, RecipeImportTable, StorageTable
@group_required('admin')
@@ -65,19 +65,6 @@ def storage(request):
)
-@group_required('admin')
-def home_assistant_config(request):
- table = HomeAssistantConfigTable(HomeAssistantConfig.objects.filter(space=request.space).all())
- RequestConfig(request, paginate={'per_page': 25}).configure(table)
-
- return render(
- request, 'generic/list_template.html', {
- 'title': _("HomeAssistant Config Backend"),
- 'table': table,
- 'create_url': 'new_home_assistant_config'
- })
-
-
@group_required('admin')
def invite_link(request):
table = InviteLinkTable(
diff --git a/cookbook/views/new.py b/cookbook/views/new.py
index 263dca09..22bfbc84 100644
--- a/cookbook/views/new.py
+++ b/cookbook/views/new.py
@@ -5,9 +5,9 @@ from django.urls import reverse, reverse_lazy
from django.utils.translation import gettext as _
from django.views.generic import CreateView
-from cookbook.forms import ImportRecipeForm, Storage, StorageForm, HomeAssistantConfigForm
+from cookbook.forms import ImportRecipeForm, Storage, StorageForm, HomeAssistantConfigForm, ExampleConfigForm
from cookbook.helper.permission_helper import GroupRequiredMixin, above_space_limit, group_required
-from cookbook.models import Recipe, RecipeImport, ShareLink, Step, HomeAssistantConfig
+from cookbook.models import Recipe, RecipeImport, ShareLink, Step, HomeAssistantConfig, ExampleConfig
from recipes import settings
@@ -77,6 +77,40 @@ class HomeAssistantConfigCreate(GroupRequiredMixin, CreateView):
form_class = HomeAssistantConfigForm
success_url = reverse_lazy('list_home_assistant_config')
+ def get_form_class(self):
+ form_class = super().get_form_class()
+
+ if self.request.method == 'GET':
+ update_token_field = form_class.base_fields['update_token']
+ update_token_field.required = True
+
+ return form_class
+
+ def form_valid(self, form):
+ if self.request.space.demo or settings.HOSTED:
+ messages.add_message(self.request, messages.ERROR, _('This feature is not yet available in the hosted version of tandoor!'))
+ return redirect('index')
+
+ obj = form.save(commit=False)
+ obj.token = form.cleaned_data['update_token']
+ obj.created_by = self.request.user
+ obj.space = self.request.space
+ obj.save()
+ return HttpResponseRedirect(reverse('edit_home_assistant_config', kwargs={'pk': obj.pk}))
+
+ def get_context_data(self, **kwargs):
+ context = super().get_context_data(**kwargs)
+ context['title'] = _("HomeAssistant Config Backend")
+ return context
+
+
+class ExampleConfigCreate(GroupRequiredMixin, CreateView):
+ groups_required = ['admin']
+ template_name = "generic/new_template.html"
+ model = ExampleConfig
+ form_class = ExampleConfigForm
+ success_url = reverse_lazy('list_connectors')
+
def form_valid(self, form):
if self.request.space.demo or settings.HOSTED:
messages.add_message(self.request, messages.ERROR, _('This feature is not yet available in the hosted version of tandoor!'))
@@ -86,11 +120,11 @@ class HomeAssistantConfigCreate(GroupRequiredMixin, CreateView):
obj.created_by = self.request.user
obj.space = self.request.space
obj.save()
- return HttpResponseRedirect(reverse('edit_home_assistant_config', kwargs={'pk': obj.pk}))
+ return HttpResponseRedirect(reverse('edit_example_config', kwargs={'pk': obj.pk}))
def get_context_data(self, **kwargs):
- context = super(HomeAssistantConfigCreate, self).get_context_data(**kwargs)
- context['title'] = _("HomeAssistant Config Backend")
+ context = super().get_context_data(**kwargs)
+ context['title'] = _("Example Config Backend")
return context