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.