diff --git a/openslides/core/config.py b/openslides/core/config.py
index 390f43b5a..29f06a93d 100644
--- a/openslides/core/config.py
+++ b/openslides/core/config.py
@@ -101,7 +101,12 @@ class ConfigHandler:
raise ConfigError(_('public property has to be bool.'))
# Save the new value to the database.
- ConfigStore.objects.update_or_create(key=key, defaults={'value': value})
+ try:
+ db_value = ConfigStore.objects.get(key=key)
+ except ConfigStore.DoesNotExist:
+ db_value = ConfigStore(key=key)
+ db_value.value = value
+ db_value.save(information={'changed_config': key})
# Call on_change callback.
if config_variable.on_change:
diff --git a/openslides/core/models.py b/openslides/core/models.py
index bdb6d0c40..2409fca7e 100644
--- a/openslides/core/models.py
+++ b/openslides/core/models.py
@@ -3,8 +3,9 @@ from django.contrib.sessions.models import Session as DjangoSession
from django.db import models
from jsonfield import JSONField
-from openslides.utils.models import RESTModelMixin
-from openslides.utils.projector import ProjectorElement
+from ..utils.collection import CollectionElement
+from ..utils.models import RESTModelMixin
+from ..utils.projector import ProjectorElement
from .access_permissions import (
ChatMessageAccessPermissions,
@@ -149,12 +150,13 @@ class Projector(RESTModelMixin, models.Model):
def get_collection_elements_required_for_this(self, collection_element):
"""
Returns an iterable of CollectionElements that have to be sent to this
- projector according to the given collection_element and information.
+ projector according to the given collection_element.
"""
from .config import config
output = []
changed_fields = collection_element.information.get('changed_fields', [])
+
if (collection_element.collection_string == self.get_collection_string() and
changed_fields and
'config' not in changed_fields):
@@ -165,15 +167,29 @@ class Projector(RESTModelMixin, models.Model):
this_projector = collection_element.collection_string == self.get_collection_string() and collection_element.id == self.pk
collection_element.information['this_projector'] = this_projector
elements = {}
+
+ # Build projector elements.
for element in ProjectorElement.get_all():
elements[element.name] = element
+
+ # Iterate over all active projector elements.
for key, value in self.config.items():
element = elements.get(value['name'])
if element is not None:
- output.extend(element.get_collection_elements_required_for_this(collection_element, value))
- # If config changed, send also this to the projector.
+ if collection_element.information.get('changed_config') == 'projector_broadcast':
+ # In case of broadcast we need full update.
+ output.extend(element.get_requirements_as_collection_elements(value))
+ else:
+ # In normal case we need all collections required by the element.
+ output.extend(element.get_collection_elements_required_for_this(collection_element, value))
+
+ # If config changed, send also this config to the projector.
if collection_element.collection_string == config.get_collection_string():
output.append(collection_element)
+ if collection_element.information.get('changed_config') == 'projector_broadcast':
+ # In case of broadcast we also need the projector himself.
+ output.append(CollectionElement.from_instance(self))
+
return output
diff --git a/openslides/core/static/templates/core/manage-projectors.html b/openslides/core/static/templates/core/manage-projectors.html
index fe115510e..947f4a1d8 100644
--- a/openslides/core/static/templates/core/manage-projectors.html
+++ b/openslides/core/static/templates/core/manage-projectors.html
@@ -36,7 +36,7 @@
-
+
{{ projector.id }}:
diff --git a/openslides/utils/autoupdate.py b/openslides/utils/autoupdate.py
index 18ec21e9b..f45258207 100644
--- a/openslides/utils/autoupdate.py
+++ b/openslides/utils/autoupdate.py
@@ -49,7 +49,7 @@ def ws_add_projector(message, projector_id):
"""
user = message.user
# user is the django anonymous user. We have our own.
- if user.is_anonymous and config['general_systen_enable_anonymous']:
+ if user.is_anonymous and config['general_system_enable_anonymous']:
user = AnonymousUser()
if not user.has_perm('core.can_see_projector'):
@@ -64,21 +64,30 @@ def ws_add_projector(message, projector_id):
# informed if the data change.
Group('projector-{}'.format(projector_id)).add(message.reply_channel)
- # Send all elements that are on the projector.
+ # Then it is also added to the global projector group which is
+ # used for broadcasting data.
+ Group('projector-all').add(message.reply_channel)
+
+ # Now check whether broadcast is active at the moment. If yes,
+ # change the local projector variable.
+ if config['projector_broadcast'] > 0:
+ projector = Projector.objects.get(pk=config['projector_broadcast'])
+
+ # Collect all elements that are on the projector.
output = []
for requirement in projector.get_all_requirements():
required_collection_element = CollectionElement.from_instance(requirement)
output.append(required_collection_element.as_autoupdate_for_projector())
- # Send all config elements.
+ # Collect all config elements.
collection = Collection(config.get_collection_string())
output.extend(collection.as_autoupdate_for_projector())
- # Send the projector instance.
+ # Collect the projector instance.
collection_element = CollectionElement.from_instance(projector)
output.append(collection_element.as_autoupdate_for_projector())
- # Send all the data that was only collected before
+ # Send all the data that were only collected before.
message.reply_channel.send({'text': json.dumps(output)})
@@ -101,16 +110,27 @@ def send_data(message):
output = [collection_element.as_autoupdate_for_user(user)]
channel.send({'text': json.dumps(output)})
+ # Check whether broadcast is active at the moment and set the local
+ # projector queryset.
+ if config['projector_broadcast'] > 0:
+ queryset = Projector.objects.filter(pk=config['projector_broadcast'])
+ else:
+ queryset = Projector.objects.all()
+
# Loop over all projectors and send data that they need.
- for projector in Projector.objects.all():
+ for projector in queryset:
if collection_element.is_deleted():
output = [collection_element.as_autoupdate_for_projector()]
else:
collection_elements = projector.get_collection_elements_required_for_this(collection_element)
output = [collection_element.as_autoupdate_for_projector() for collection_element in collection_elements]
if output:
- Group('projector-{}'.format(projector.pk)).send(
- {'text': json.dumps(output)})
+ if config['projector_broadcast'] > 0:
+ Group('projector-all').send(
+ {'text': json.dumps(output)})
+ else:
+ Group('projector-{}'.format(projector.pk)).send(
+ {'text': json.dumps(output)})
def inform_changed_data(instance, information=None):
diff --git a/openslides/utils/projector.py b/openslides/utils/projector.py
index 5f3686211..db6f20216 100644
--- a/openslides/utils/projector.py
+++ b/openslides/utils/projector.py
@@ -85,7 +85,7 @@ class ProjectorElement(object, metaclass=SignalConnectMetaClass):
"""
Returns a list of CollectionElements that have to be sent to every
projector that shows this projector element according to the given
- collection_element and information.
+ collection_element.
Default: Returns only the collection_element if it belongs to the
requirements but return all requirements if the projector changes.