Fixed broadcast. Fixed #2467.

This commit is contained in:
Norman Jäckel 2016-10-01 12:58:49 +02:00
parent 5879702354
commit 2e7555e720
5 changed files with 57 additions and 16 deletions

View File

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

View File

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

View File

@ -36,7 +36,7 @@
<div class="details">
<div class="projectorContainer">
<div ng-repeat="projector in projectors">
<div ng-repeat="projector in projectors | orderBy: 'id'">
<div>
<a ui-sref="projector({id: projector.id})">
{{ projector.id }}:

View File

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

View File

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