add an config toggle for external connectors

This commit is contained in:
Mikhail Epifanov 2024-01-12 22:20:55 +01:00
parent d576394c99
commit 445e64c71e
No known key found for this signature in database
6 changed files with 38 additions and 19 deletions

View File

@ -1,6 +1,7 @@
import asyncio import asyncio
import logging import logging
import multiprocessing import multiprocessing
import queue
from asyncio import Task from asyncio import Task
from dataclasses import dataclass from dataclasses import dataclass
from enum import Enum from enum import Enum
@ -55,7 +56,10 @@ class ConnectorManager:
else: else:
return return
try:
self._queue.put_nowait(Payload(instance, action_type)) self._queue.put_nowait(Payload(instance, action_type))
except queue.Full:
return
def stop(self): def stop(self):
self._queue.close() self._queue.close()

View File

@ -1,4 +1,4 @@
# Generated by Django 4.2.7 on 2024-01-11 22:06 # Generated by Django 4.2.7 on 2024-01-12 21:01
import cookbook.models import cookbook.models
from django.conf import settings from django.conf import settings
@ -20,16 +20,19 @@ class Migration(migrations.Migration):
fields=[ fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('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)])), ('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)),
('url', models.URLField(blank=True)), ('url', models.URLField(blank=True)),
('token', models.CharField(blank=True, max_length=512)), ('token', models.CharField(blank=True, max_length=512)),
('todo_entity', models.CharField(default='todo.shopping_list', max_length=128)), ('todo_entity', models.CharField(default='todo.shopping_list', max_length=128)),
('enabled', models.BooleanField(default=True, help_text='Is HomeAssistant Connector Enabled')),
('on_shopping_list_entry_created_enabled', models.BooleanField(default=False, help_text='Enable syncing ShoppingListEntry to Homeassistant Todo List')),
('on_shopping_list_entry_updated_enabled', models.BooleanField(default=False, help_text='PLACEHOLDER')),
('on_shopping_list_entry_deleted_enabled', models.BooleanField(default=False, help_text='Enable syncing ShoppingListEntry deletion to Homeassistant Todo List')),
('created_by', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)), ('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')), ('space', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cookbook.space')),
], ],
options={
'abstract': False,
},
bases=(models.Model, cookbook.models.PermissionModelMixin), bases=(models.Model, cookbook.models.PermissionModelMixin),
), ),
] ]

View File

@ -366,24 +366,28 @@ class Space(ExportModelOperationsMixin('space'), models.Model):
return self.name return self.name
class HomeAssistantConfig(models.Model, PermissionModelMixin): class ConnectorConfig(models.Model, PermissionModelMixin):
name = models.CharField(max_length=128, validators=[MinLengthValidator(1)]) name = models.CharField(max_length=128, validators=[MinLengthValidator(1)])
url = models.URLField(blank=True) enabled = models.BooleanField(default=True, help_text="Is Connector Enabled")
token = models.CharField(max_length=512, blank=True) on_shopping_list_entry_created_enabled = models.BooleanField(default=False)
on_shopping_list_entry_updated_enabled = models.BooleanField(default=False)
todo_entity = models.CharField(max_length=128, default='todo.shopping_list') on_shopping_list_entry_deleted_enabled = models.BooleanField(default=False)
enabled = models.BooleanField(default=True, help_text="Is HomeAssistant Connector Enabled")
on_shopping_list_entry_created_enabled = models.BooleanField(default=False, help_text="Enable syncing ShoppingListEntry to Homeassistant Todo List")
on_shopping_list_entry_updated_enabled = models.BooleanField(default=False, help_text="PLACEHOLDER")
on_shopping_list_entry_deleted_enabled = models.BooleanField(default=False, help_text="Enable syncing ShoppingListEntry deletion to Homeassistant Todo List")
created_by = models.ForeignKey(User, on_delete=models.PROTECT) created_by = models.ForeignKey(User, on_delete=models.PROTECT)
space = models.ForeignKey(Space, on_delete=models.CASCADE) space = models.ForeignKey(Space, on_delete=models.CASCADE)
objects = ScopedManager(space='space') objects = ScopedManager(space='space')
class Meta:
abstract = True
class HomeAssistantConfig(ConnectorConfig):
url = models.URLField(blank=True)
token = models.CharField(max_length=512, blank=True)
todo_entity = models.CharField(max_length=128, default='todo.shopping_list')
class UserPreference(models.Model, PermissionModelMixin): class UserPreference(models.Model, PermissionModelMixin):
# Themes # Themes

View File

@ -15,6 +15,7 @@ from cookbook.helper.shopping_helper import RecipeShoppingEditor
from cookbook.managers import DICTIONARY from cookbook.managers import DICTIONARY
from cookbook.models import (Food, MealPlan, PropertyType, Recipe, SearchFields, SearchPreference, from cookbook.models import (Food, MealPlan, PropertyType, Recipe, SearchFields, SearchPreference,
Step, Unit, UserPreference) Step, Unit, UserPreference)
from recipes.settings import ENABLE_EXTERNAL_CONNECTORS
SQLITE = True SQLITE = True
if settings.DATABASES['default']['ENGINE'] == 'django.db.backends.postgresql': if settings.DATABASES['default']['ENGINE'] == 'django.db.backends.postgresql':
@ -164,6 +165,7 @@ def clear_property_type_cache(sender, instance=None, created=False, **kwargs):
caches['default'].delete(CacheHelper(instance.space).PROPERTY_TYPE_CACHE_KEY) caches['default'].delete(CacheHelper(instance.space).PROPERTY_TYPE_CACHE_KEY)
handler = ConnectorManager() if ENABLE_EXTERNAL_CONNECTORS:
post_save.connect(handler, dispatch_uid="connector_manager") handler = ConnectorManager()
post_delete.connect(handler, dispatch_uid="connector_manager") post_save.connect(handler, dispatch_uid="connector_manager")
post_delete.connect(handler, dispatch_uid="connector_manager")

View File

@ -335,6 +335,10 @@
<a class="dropdown-item" href="{% url 'view_space_manage' request.space.pk %}"><i <a class="dropdown-item" href="{% url 'view_space_manage' request.space.pk %}"><i
class="fas fa-server fa-fw"></i> {% trans 'Space Settings' %}</a> class="fas fa-server fa-fw"></i> {% trans 'Space Settings' %}</a>
{% endif %} {% endif %}
{% if request.user == request.space.created_by or user.is_superuser %}
<a class="dropdown-item" href="{% url 'list_home_assistant_config' %}"><i
class="fas fa-sync-alt fa-fw"></i> {% trans 'External Connectors' %}</a>
{% endif %}
{% if user.is_superuser %} {% if user.is_superuser %}
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item" href="{% url 'view_system' %}"><i <a class="dropdown-item" href="{% url 'view_system' %}"><i

View File

@ -554,4 +554,6 @@ DEFAULT_FROM_EMAIL = os.getenv('DEFAULT_FROM_EMAIL', 'webmaster@localhost')
ACCOUNT_EMAIL_SUBJECT_PREFIX = os.getenv( ACCOUNT_EMAIL_SUBJECT_PREFIX = os.getenv(
'ACCOUNT_EMAIL_SUBJECT_PREFIX', '[Tandoor Recipes] ') # allauth sender prefix 'ACCOUNT_EMAIL_SUBJECT_PREFIX', '[Tandoor Recipes] ') # allauth sender prefix
ENABLE_EXTERNAL_CONNECTORS = bool(int(os.getenv('ENABLE_EXTERNAL_CONNECTORS', False)))
mimetypes.add_type("text/javascript", ".js", True) mimetypes.add_type("text/javascript", ".js", True)