diff --git a/CHANGELOG b/CHANGELOG index 3594e8c1a..07255d78c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -7,9 +7,13 @@ http://openslides.org Version 2.0.0 (unreleased) ========================== -- Changed supported Python version to >= 3.3 -- Used Django 1.7 as lowest requirement -- Refactoring of the participant app. Now called 'users' +Other: +- Changed supported Python version to >= 3.3. +- Used Django 1.7 as lowest requirement. +- Refactoring of the participant app. Now called 'users'. +- Added Django's application configuration. Refactored loading of signals, + template signals and slides. + Version 1.6.1 (2014-12-08) diff --git a/openslides/account/__init__.py b/openslides/account/__init__.py index a1c0c869e..217ee87bc 100644 --- a/openslides/account/__init__.py +++ b/openslides/account/__init__.py @@ -1 +1 @@ -from . import widgets # noqa +default_app_config = 'openslides.account.apps.AccountAppConfig' diff --git a/openslides/account/apps.py b/openslides/account/apps.py new file mode 100644 index 000000000..bc1350505 --- /dev/null +++ b/openslides/account/apps.py @@ -0,0 +1,10 @@ +from django.apps import AppConfig + + +class AccountAppConfig(AppConfig): + name = 'openslides.account' + verbose_name = 'OpenSlides Account' + + def ready(self): + # Load widget. + from . import widgets # noqa diff --git a/openslides/agenda/__init__.py b/openslides/agenda/__init__.py index 9e426cdbe..44b39b695 100644 --- a/openslides/agenda/__init__.py +++ b/openslides/agenda/__init__.py @@ -1 +1 @@ -from . import main_menu, personal_info, signals, slides, widgets # noqa +default_app_config = 'openslides.agenda.apps.AgendaAppConfig' diff --git a/openslides/agenda/apps.py b/openslides/agenda/apps.py new file mode 100644 index 000000000..5a1d22f3f --- /dev/null +++ b/openslides/agenda/apps.py @@ -0,0 +1,28 @@ +from django.apps import AppConfig + + +class AgendaAppConfig(AppConfig): + name = 'openslides.agenda' + verbose_name = 'OpenSlides Agenda' + + def ready(self): + # Load main menu entry, personal info and widgets. + # Do this by just importing all from these files. + from . import main_menu, personal_info, widgets # noqa + + # Import all required stuff. + from django.db.models.signals import pre_delete + from openslides.config.signals import config_signal + from openslides.projector.api import register_slide + from openslides.projector.signals import projector_overlays + from .signals import agenda_list_of_speakers, setup_agenda_config, listen_to_related_object_delete_signal + from .slides import agenda_slide + + # Connect signals. + config_signal.connect(setup_agenda_config, dispatch_uid='setup_agenda_config') + projector_overlays.connect(agenda_list_of_speakers, dispatch_uid='agenda_list_of_speakers') + pre_delete.connect(listen_to_related_object_delete_signal, dispatch_uid='agenda_listen_to_related_object_delete_signal') + + # Register slides. + Item = self.get_model('Item') + register_slide('agenda', agenda_slide, Item) diff --git a/openslides/agenda/forms.py b/openslides/agenda/forms.py index d5654a0c2..62c5420e1 100644 --- a/openslides/agenda/forms.py +++ b/openslides/agenda/forms.py @@ -1,6 +1,6 @@ import re -from ckeditor.widgets import CKEditorWidget +from ckeditor.widgets import CKEditorWidget from django import forms from django.utils.translation import ugettext_lazy from mptt.forms import TreeNodeChoiceField diff --git a/openslides/agenda/signals.py b/openslides/agenda/signals.py index d1f65c4cf..f87fae70e 100644 --- a/openslides/agenda/signals.py +++ b/openslides/agenda/signals.py @@ -3,17 +3,13 @@ from datetime import datetime from django import forms from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ValidationError -from django.db.models.signals import pre_delete -from django.dispatch import receiver from django.template.loader import render_to_string from django.utils.translation import ugettext as _ from django.utils.translation import ugettext_lazy, ugettext_noop from openslides.config.api import config, ConfigCollection, ConfigVariable -from openslides.config.signals import config_signal from openslides.projector.api import get_active_slide, get_active_object from openslides.projector.projector import Overlay -from openslides.projector.signals import projector_overlays from .models import Item @@ -27,10 +23,10 @@ def validate_start_time(value): # TODO: Reinsert the datepicker scripts in the template -@receiver(config_signal, dispatch_uid='setup_agenda_config') def setup_agenda_config(sender, **kwargs): """ - Agenda config variables. + Receiver function to setup all agenda config variables. It is connected to + the signal openslides.config.signals.config_signal during app loading. """ # TODO: Insert validator for the format or use other field carefully. agenda_start_event_date_time = ConfigVariable( @@ -94,10 +90,11 @@ def setup_agenda_config(sender, **kwargs): 'extra_javascript': extra_javascript}) -@receiver(projector_overlays, dispatch_uid="agenda_list_of_speakers") def agenda_list_of_speakers(sender, **kwargs): """ - Receiver for the list of speaker overlay. + Receiver function to setup the list of speaker overlay. It is connected + to the signal openslides.projector.signals.projector_overlays during + app loading. """ name = 'agenda_speaker' @@ -141,10 +138,11 @@ def agenda_list_of_speakers(sender, **kwargs): return Overlay(name, get_widget_html, get_projector_html) -@receiver(pre_delete) def listen_to_related_object_delete_signal(sender, instance, **kwargs): """ - Receiver to listen whether a related item has been deleted. + Receiver function to changed agenda items of a related items that is to + be deleted. It is connected to the signal + django.db.models.signals.pre_delete during app loading. """ if hasattr(instance, 'get_agenda_title'): for item in Item.objects.filter(content_type=ContentType.objects.get_for_model(sender), object_id=instance.pk): diff --git a/openslides/agenda/slides.py b/openslides/agenda/slides.py index 7c702a566..171a84086 100644 --- a/openslides/agenda/slides.py +++ b/openslides/agenda/slides.py @@ -1,7 +1,7 @@ from django.template.loader import render_to_string from openslides.config.api import config -from openslides.projector.api import get_projector_content, register_slide +from openslides.projector.api import get_projector_content from .models import Item @@ -19,6 +19,8 @@ def agenda_slide(**kwargs): If 'type' is 'summary', show a summary of all children of the item. If 'type' is 'list_of_speakers', show the list of speakers for the item. + + The function is registered during app loading. """ item_pk = kwargs.get('pk', None) slide_type = kwargs.get('type', None) @@ -56,6 +58,3 @@ def agenda_slide(**kwargs): context = {'item': item} slide = render_to_string('agenda/item_slide.html', context) return slide - - -register_slide('agenda', agenda_slide, Item) diff --git a/openslides/assignment/__init__.py b/openslides/assignment/__init__.py index eff95fa33..5eff81229 100644 --- a/openslides/assignment/__init__.py +++ b/openslides/assignment/__init__.py @@ -1 +1 @@ -# TODO: apploader +default_app_config = 'openslides.assignment.apps.AssignmentAppConfig' diff --git a/openslides/assignment/apps.py b/openslides/assignment/apps.py new file mode 100644 index 000000000..1331ed1e8 --- /dev/null +++ b/openslides/assignment/apps.py @@ -0,0 +1,30 @@ +from django.apps import AppConfig + + +class AssignmentAppConfig(AppConfig): + name = 'openslides.assignment' + verbose_name = 'OpenSlides Assignment' + + def ready(self): + # Load main menu entry, personal info and widgets. + # Do this by just importing all from these files. + from . import main_menu, personal_info, widgets # noqa + + # Import all required stuff. + from openslides.config.signals import config_signal + from openslides.projector.api import register_slide_model + from openslides.utils.signals import template_manipulation + from .signals import setup_assignment_config + from .template import add_assignment_stylesheets + + # Connect signals. + config_signal.connect(setup_assignment_config, dispatch_uid='setup_assignment_config') + + # Connect template signal. + template_manipulation.connect(add_assignment_stylesheets, dispatch_uid='add_assignment_stylesheets') + + # Register slides. + Assignment = self.get_model('Assignment') + AssignmentPoll = self.get_model('AssignmentPoll') + register_slide_model(Assignment, 'assignment/slide.html') + register_slide_model(AssignmentPoll, 'assignment/assignmentpoll_slide.html') diff --git a/openslides/assignment/models.py b/openslides/assignment/models.py index 460c86780..dd9cd17ef 100644 --- a/openslides/assignment/models.py +++ b/openslides/assignment/models.py @@ -342,7 +342,3 @@ class AssignmentPoll(SlideMixin, RelatedModelMixin, CollectDefaultVotesMixin, def get_slide_context(self, **context): return super(AssignmentPoll, self).get_slide_context(poll=self) - - -# TODO: use the app framework -from . import main_menu, personal_info, signals, slides, template, widgets # noqa diff --git a/openslides/assignment/signals.py b/openslides/assignment/signals.py index ca71339fa..56774c30e 100644 --- a/openslides/assignment/signals.py +++ b/openslides/assignment/signals.py @@ -1,17 +1,16 @@ from django import forms -from django.dispatch import receiver from django.utils.translation import ugettext as _ from django.utils.translation import ugettext_lazy, ugettext_noop from openslides.config.api import ConfigGroup, ConfigGroupedCollection, ConfigVariable -from openslides.config.signals import config_signal from openslides.poll.models import PERCENT_BASE_CHOICES -@receiver(config_signal, dispatch_uid='setup_assignment_config') def setup_assignment_config(sender, **kwargs): """ - Assignment config variables. + Receiver function to setup all assignment config variables. It is + connected to the signal openslides.config.signals.config_signal during + app loading. """ # Ballot and ballot papers assignment_poll_vote_values = ConfigVariable( diff --git a/openslides/assignment/slides.py b/openslides/assignment/slides.py deleted file mode 100644 index d3627c109..000000000 --- a/openslides/assignment/slides.py +++ /dev/null @@ -1,6 +0,0 @@ -from openslides.projector.api import register_slide_model - -from .models import Assignment, AssignmentPoll - -register_slide_model(Assignment, 'assignment/slide.html') -register_slide_model(AssignmentPoll, 'assignment/assignmentpoll_slide.html') diff --git a/openslides/assignment/template.py b/openslides/assignment/template.py index 0df923112..5cb21bb03 100644 --- a/openslides/assignment/template.py +++ b/openslides/assignment/template.py @@ -1,11 +1,7 @@ -from django.dispatch import receiver - -from openslides.utils.signals import template_manipulation - - -@receiver(template_manipulation, dispatch_uid="add_assignment_stylesheets") def add_assignment_stylesheets(sender, request, context, **kwargs): """ - Adds the assignment.css to the context. + Receiver function to add the assignment.css to the context. It is + connected to the signal openslides.utils.signals.template_manipulation + during app loading. """ context['extra_stylefiles'].append('css/assignment.css') diff --git a/openslides/config/__init__.py b/openslides/config/__init__.py index 8d15e06d4..2c5bdbda5 100644 --- a/openslides/config/__init__.py +++ b/openslides/config/__init__.py @@ -1 +1 @@ -from . import main_menu # noqa +default_app_config = 'openslides.config.apps.ConfigAppConfig' diff --git a/openslides/config/apps.py b/openslides/config/apps.py new file mode 100644 index 000000000..5fe9d414a --- /dev/null +++ b/openslides/config/apps.py @@ -0,0 +1,11 @@ +from django.apps import AppConfig + + +class ConfigAppConfig(AppConfig): + name = 'openslides.config' + verbose_name = 'OpenSlides Config' + + def ready(self): + # Load main menu entry. + # Do this by just importing all from this file. + from . import main_menu # noqa diff --git a/openslides/core/__init__.py b/openslides/core/__init__.py index b0ad1bf8f..8c0054d41 100644 --- a/openslides/core/__init__.py +++ b/openslides/core/__init__.py @@ -1 +1 @@ -# TODO: apploading +default_app_config = 'openslides.core.apps.CoreAppConfig' diff --git a/openslides/core/apps.py b/openslides/core/apps.py new file mode 100644 index 000000000..fb0fa62e0 --- /dev/null +++ b/openslides/core/apps.py @@ -0,0 +1,23 @@ +from django.apps import AppConfig + + +class CoreAppConfig(AppConfig): + name = 'openslides.core' + verbose_name = 'OpenSlides Core' + + def ready(self): + # Load main menu entry and widgets. + # Do this by just importing all from these files. + from . import main_menu, widgets # noqa + + # Import all required stuff. + from openslides.config.signals import config_signal + from openslides.projector.api import register_slide_model + from .signals import setup_general_config + + # Connect signals. + config_signal.connect(setup_general_config, dispatch_uid='setup_general_config') + + # Register slides. + CustomSlide = self.get_model('CustomSlide') + register_slide_model(CustomSlide, 'core/customslide_slide.html') diff --git a/openslides/core/models.py b/openslides/core/models.py index 86b5a4783..f9a8aef42 100644 --- a/openslides/core/models.py +++ b/openslides/core/models.py @@ -44,7 +44,3 @@ class CustomSlide(SlideMixin, AbsoluteUrlMixin, models.Model): else: url = super(CustomSlide, self).get_absolute_url(link) return url - - -# TODO: apploader -from . import main_menu, signals, slides, widgets # noqa diff --git a/openslides/core/signals.py b/openslides/core/signals.py index 4cf36ae16..aae6de38d 100644 --- a/openslides/core/signals.py +++ b/openslides/core/signals.py @@ -1,20 +1,20 @@ from django import forms -from django.dispatch import receiver, Signal +from django.dispatch import Signal from django.utils.translation import ugettext as _ from django.utils.translation import ugettext_lazy, ugettext_noop from openslides.config.api import ConfigGroup, ConfigGroupedCollection, ConfigVariable -from openslides.config.signals import config_signal from openslides.projector.api import update_projector post_database_setup = Signal() -@receiver(config_signal, dispatch_uid='setup_general_config') def setup_general_config(sender, **kwargs): """ - General config variables for OpenSlides. They are grouped in 'Event', - 'Welcome Widget' and 'System'. + Receiver function to setup general config variables for OpenSlides. + They are grouped in 'Event', 'Welcome Widget' and 'System'. The + function is connected to the signal + openslides.config.signals.config_signal during app loading. """ event_name = ConfigVariable( name='event_name', diff --git a/openslides/core/slides.py b/openslides/core/slides.py deleted file mode 100644 index 1a6e4e948..000000000 --- a/openslides/core/slides.py +++ /dev/null @@ -1,5 +0,0 @@ -from openslides.projector.api import register_slide_model - -from .models import CustomSlide - -register_slide_model(CustomSlide, 'core/customslide_slide.html') diff --git a/openslides/core/widgets.py b/openslides/core/widgets.py index 5b809f9cd..f5a350cdb 100644 --- a/openslides/core/widgets.py +++ b/openslides/core/widgets.py @@ -36,8 +36,11 @@ class CustonSlideWidget(Widget): icon_css_class = 'icon-star' def get_context_data(self, **context): - return super(CustonSlideWidget, self).get_context_data( - slides=CustomSlide.objects.all().order_by('weight'), - welcomepage_is_active=( - get_active_slide().get('callback', 'default') == 'default'), - **context) + """ + Adds custom slides and a flag whether the welcome page is active to + the context. + """ + context['slides'] = CustomSlide.objects.all().order_by('weight') + context['welcomepage_is_active'] = ( + get_active_slide().get('callback', 'default') == 'default') + return super(CustonSlideWidget, self).get_context_data(**context) diff --git a/openslides/mediafile/__init__.py b/openslides/mediafile/__init__.py index a308af592..352bdc7eb 100644 --- a/openslides/mediafile/__init__.py +++ b/openslides/mediafile/__init__.py @@ -1 +1 @@ -from . import main_menu, slides, template, widgets # noqa +default_app_config = 'openslides.mediafile.apps.MediafileAppConfig' diff --git a/openslides/mediafile/apps.py b/openslides/mediafile/apps.py new file mode 100644 index 000000000..9dc0b4b92 --- /dev/null +++ b/openslides/mediafile/apps.py @@ -0,0 +1,24 @@ +from django.apps import AppConfig + + +class MediafileAppConfig(AppConfig): + name = 'openslides.mediafile' + verbose_name = 'OpenSlides Mediafile' + + def ready(self): + # Load main menu entry and widgets. + # Do this by just importing all from these files. + from . import main_menu, widgets # noqa + + # Import all required stuff. + from openslides.projector.api import register_slide + from openslides.utils.signals import template_manipulation + from .slides import mediafile_presentation_as_slide + from .template import add_mediafile_stylesheets + + # Connect template signal. + template_manipulation.connect(add_mediafile_stylesheets, dispatch_uid='add_mediafile_stylesheets') + + # Register slides. + Mediafile = self.get_model('Mediafile') + register_slide('mediafile', mediafile_presentation_as_slide, Mediafile) diff --git a/openslides/mediafile/slides.py b/openslides/mediafile/slides.py index da1b8feab..84d69621e 100644 --- a/openslides/mediafile/slides.py +++ b/openslides/mediafile/slides.py @@ -1,9 +1,7 @@ -#!/usr/bin/env python - from django.template.loader import render_to_string from openslides.config.api import config -from openslides.projector.api import register_slide, SlideError +from openslides.projector.api import SlideError from .models import Mediafile @@ -13,6 +11,8 @@ def mediafile_presentation_as_slide(**kwargs): Return the html code for a presentation of a Mediafile. At the moment, only the presentation of pdfs is supported. + + The function is registered during app loading. """ file_pk = kwargs.get('pk', None) page_num = kwargs.get('page_num', 1) @@ -27,6 +27,3 @@ def mediafile_presentation_as_slide(**kwargs): context = {'pdf': pdf, 'page_num': page_num, 'fullscreen': config['pdf_fullscreen']} return render_to_string('mediafile/presentation_slide.html', context) - - -register_slide('mediafile', mediafile_presentation_as_slide, Mediafile) diff --git a/openslides/mediafile/template.py b/openslides/mediafile/template.py index 6d4c61bf2..90dc78de1 100644 --- a/openslides/mediafile/template.py +++ b/openslides/mediafile/template.py @@ -1,11 +1,7 @@ -from django.dispatch import receiver - -from openslides.utils.signals import template_manipulation - - -@receiver(template_manipulation, dispatch_uid="add_mediafile_stylesheets") def add_mediafile_stylesheets(sender, request, context, **kwargs): """ - Adds the mediafile.css to the context. + Receiver function to add the mediafile.css to the context. It is + connected to the signal openslides.utils.signals.template_manipulation + during app loading. """ context['extra_stylefiles'].append('css/mediafile.css') diff --git a/openslides/motion/__init__.py b/openslides/motion/__init__.py index 498f2dd6f..544a0c792 100644 --- a/openslides/motion/__init__.py +++ b/openslides/motion/__init__.py @@ -1 +1 @@ -# TODO: Apploading +default_app_config = 'openslides.motion.apps.MotionAppConfig' diff --git a/openslides/motion/apps.py b/openslides/motion/apps.py new file mode 100644 index 000000000..e5ecdfe71 --- /dev/null +++ b/openslides/motion/apps.py @@ -0,0 +1,27 @@ +from django.apps import AppConfig + + +class MotionAppConfig(AppConfig): + name = 'openslides.motion' + verbose_name = 'OpenSlides Motion' + + def ready(self): + # Load main menu entry, personal info and widgets. + # Do this by just importing all from these files. + from . import main_menu, personal_info, widgets # noqa + + # Import all required stuff. + from openslides.config.signals import config_signal + from openslides.core.signals import post_database_setup + from openslides.projector.api import register_slide_model + from .signals import create_builtin_workflows, setup_motion_config + + # Connect signals. + config_signal.connect(setup_motion_config, dispatch_uid='setup_motion_config') + post_database_setup.connect(create_builtin_workflows, dispatch_uid='motion_create_builtin_workflows') + + # Register slides. + Motion = self.get_model('Motion') + MotionPoll = self.get_model('MotionPoll') + register_slide_model(Motion, 'motion/slide.html') + register_slide_model(MotionPoll, 'motion/motionpoll_slide.html') diff --git a/openslides/motion/models.py b/openslides/motion/models.py index bc7ad0e2d..669a3442c 100644 --- a/openslides/motion/models.py +++ b/openslides/motion/models.py @@ -852,7 +852,3 @@ class Workflow(models.Model): raise WorkflowError( '%s can not be first state of %s because it ' 'does not belong to it.' % (self.first_state, self)) - - -# TODO: Apploading -from . import main_menu, personal_info, signals, slides, widgets # noqa diff --git a/openslides/motion/signals.py b/openslides/motion/signals.py index 6b030471d..69d1ebf1b 100644 --- a/openslides/motion/signals.py +++ b/openslides/motion/signals.py @@ -1,20 +1,17 @@ from django import forms -from django.dispatch import receiver from django.utils.translation import ugettext as _ from django.utils.translation import ugettext_lazy, ugettext_noop from openslides.config.api import ConfigGroup, ConfigGroupedCollection, ConfigVariable -from openslides.config.signals import config_signal -from openslides.core.signals import post_database_setup from openslides.poll.models import PERCENT_BASE_CHOICES from .models import State, Workflow -@receiver(config_signal, dispatch_uid='setup_motion_config') def setup_motion_config(sender, **kwargs): """ - Motion config variables. + Receiver function to setup all motion config variables. It is connected to + the signal openslides.config.signals.config_signal during app loading. """ # General motion_workflow = ConfigVariable( @@ -149,10 +146,11 @@ def setup_motion_config(sender, **kwargs): groups=(group_general, group_supporters, group_ballot_papers, group_pdf)) -@receiver(post_database_setup, dispatch_uid='motion_create_builtin_workflows') def create_builtin_workflows(sender, **kwargs): """ - Creates a simple and a complex workflow. + Receiver function to create a simple and a complex workflow. It is + connected to the signal openslides.core.signals.post_database_setup + during app loading. """ workflow_1, created = Workflow.objects.get_or_create(name=ugettext_noop('Simple Workflow')) if created: diff --git a/openslides/motion/slides.py b/openslides/motion/slides.py deleted file mode 100644 index ae4472e64..000000000 --- a/openslides/motion/slides.py +++ /dev/null @@ -1,6 +0,0 @@ -from openslides.projector.api import register_slide_model - -from .models import Motion, MotionPoll - -register_slide_model(Motion, 'motion/slide.html') -register_slide_model(MotionPoll, 'motion/motionpoll_slide.html') diff --git a/openslides/poll/__init__.py b/openslides/poll/__init__.py index e69de29bb..3fc3b0abb 100644 --- a/openslides/poll/__init__.py +++ b/openslides/poll/__init__.py @@ -0,0 +1,2 @@ +# This app uses Django's base AppConfig class so the variable +# default_app_config is not defined. diff --git a/openslides/projector/__init__.py b/openslides/projector/__init__.py index 05f9e673d..f610c41af 100644 --- a/openslides/projector/__init__.py +++ b/openslides/projector/__init__.py @@ -1 +1 @@ -from . import signals, widgets # noqa +default_app_config = 'openslides.projector.apps.ProjectorAppConfig' diff --git a/openslides/projector/apps.py b/openslides/projector/apps.py new file mode 100644 index 000000000..5c02769c1 --- /dev/null +++ b/openslides/projector/apps.py @@ -0,0 +1,23 @@ +from django.apps import AppConfig + + +class ProjectorAppConfig(AppConfig): + name = 'openslides.projector' + verbose_name = 'OpenSlides Projector' + + def ready(self): + # Load widgets. + # Do this by just importing all from this file. + from . import widgets # noqa + + # Import all required stuff. + from openslides.config.signals import config_signal + from .signals import ( + countdown, projector_clock, projector_overlays, + projector_overlay_message, setup_projector_config) + + # Connect signals. + config_signal.connect(setup_projector_config, dispatch_uid='setup_projector_config') + projector_overlays.connect(countdown, dispatch_uid="projector_countdown") + projector_overlays.connect(projector_overlay_message, dispatch_uid="projector_overlay_message") + projector_overlays.connect(projector_clock, dispatch_uid="projector_clock") diff --git a/openslides/projector/projector.py b/openslides/projector/projector.py index 418450d42..0d14b29de 100644 --- a/openslides/projector/projector.py +++ b/openslides/projector/projector.py @@ -1,6 +1,5 @@ import warnings - from openslides.config.api import config from .exceptions import ProjectorExceptionWarning diff --git a/openslides/projector/signals.py b/openslides/projector/signals.py index 973c3737a..b75710e29 100644 --- a/openslides/projector/signals.py +++ b/openslides/projector/signals.py @@ -2,23 +2,22 @@ from time import time from django.contrib.staticfiles.templatetags.staticfiles import static from django.core.context_processors import csrf -from django.dispatch import receiver, Signal +from django.dispatch import Signal from django.template.loader import render_to_string from django.utils.datastructures import SortedDict from openslides.config.api import config, ConfigCollection, ConfigVariable -from openslides.config.signals import config_signal from .projector import Overlay projector_overlays = Signal(providing_args=['request']) -@receiver(config_signal, dispatch_uid='setup_projector_config') def setup_projector_config(sender, **kwargs): """ - Projector config variables for OpenSlides. They are not shown on a - config view. + Receiver function to setup all projector config variables. They are not + shown on a config view. The function is connected to the signal + openslides.config.signals.config_signal during app loading. """ # The active slide. The config-value is a dictonary with at least the entry # 'callback'. @@ -75,10 +74,10 @@ def setup_projector_config(sender, **kwargs): projector_pdf_fullscreen)) -@receiver(projector_overlays, dispatch_uid="projector_countdown") def countdown(sender, **kwargs): """ - Receiver for the countdown. + Receiver function for the projector countdown. The function is + connected to the signal projector_overlays during app loading. """ name = 'projector_countdown' request = kwargs.get('request', None) @@ -116,11 +115,11 @@ def countdown(sender, **kwargs): return Overlay(name, get_widget_html, get_projector_html, get_projector_js) -@receiver(projector_overlays, dispatch_uid="projector_overlay_message") def projector_overlay_message(sender, **kwargs): """ - Receiver to show the overlay_message on the projector or the form in the - overlay-widget on the dashboard. + Receiver function to show the overlay_message on the projector or the + form in the overlay-widget on the dashboard. The function is connected + to the signal projector_overlays during app loading. """ name = 'projector_message' request = kwargs.get('request', None) @@ -143,10 +142,10 @@ def projector_overlay_message(sender, **kwargs): return Overlay(name, get_widget_html, get_projector_html) -@receiver(projector_overlays, dispatch_uid="projector_clock") def projector_clock(sender, **kwargs): """ - Receiver to show the clock on the projector. + Receiver function to show the clock on the projector. The function is + connected to the signal projector_overlays during app loading. """ name = 'projector_clock' diff --git a/openslides/users/__init__.py b/openslides/users/__init__.py index a5dd689db..a12602089 100644 --- a/openslides/users/__init__.py +++ b/openslides/users/__init__.py @@ -1 +1 @@ -from . import main_menu, signals, slides, widgets # noqa +default_app_config = 'openslides.users.apps.UsersAppConfig' diff --git a/openslides/users/apps.py b/openslides/users/apps.py new file mode 100644 index 000000000..33b66a983 --- /dev/null +++ b/openslides/users/apps.py @@ -0,0 +1,29 @@ +from django.apps import AppConfig + + +class UsersAppConfig(AppConfig): + name = 'openslides.users' + verbose_name = 'OpenSlides Users' + + def ready(self): + # Load main menu entry and widgets. + # Do this by just importing all from these files. + from . import main_menu, widgets # noqa + + # Import all required stuff. + from django.db.models.signals import post_save + from openslides.config.signals import config_signal + from openslides.core.signals import post_database_setup + from openslides.projector.api import register_slide_model + from .signals import create_builtin_groups_and_admin, setup_users_config, user_post_save + + # Load User model. + User = self.get_model('User') + + # Connect signals. + config_signal.connect(setup_users_config, dispatch_uid='setup_users_config') + post_database_setup.connect(create_builtin_groups_and_admin, dispatch_uid='users_create_builtin_groups_and_admin') + post_save.connect(user_post_save, sender=User, dispatch_uid='users_user_post_save') + + # Register slides. + register_slide_model(User, 'participant/user_slide.html') diff --git a/openslides/users/signals.py b/openslides/users/signals.py index 5c44da2fc..af0be40f9 100644 --- a/openslides/users/signals.py +++ b/openslides/users/signals.py @@ -1,23 +1,19 @@ from django import forms from django.contrib.auth.models import Permission from django.contrib.contenttypes.models import ContentType -from django.dispatch import receiver from django.utils.translation import ugettext as _ from django.utils.translation import ugettext_lazy, ugettext_noop -from django.db.models import signals from openslides.config.api import ConfigGroup, ConfigGroupedCollection, ConfigVariable -from openslides.config.signals import config_signal -from openslides.core.signals import post_database_setup from .api import create_or_reset_admin_user -from .models import Group, User +from .models import Group -@receiver(config_signal, dispatch_uid='setup_users_config') def setup_users_config(sender, **kwargs): """ - Participant config variables. + Receiver function to setup all users config variables. It is connected + to the signal openslides.config.signals.config_signal during app loading. """ # General users_sort_users_by_first_name = ConfigVariable( @@ -108,14 +104,16 @@ def setup_users_config(sender, **kwargs): groups=(group_general, group_pdf)) -@receiver(post_database_setup, dispatch_uid='users_create_builtin_groups_and_admin') def create_builtin_groups_and_admin(sender, **kwargs): """ - Creates the buildin groups and the admin user. + Receiver function to builtin groups and the admin user. Creates the builtin groups: Anonymous, Registered, Delegates and Staff. Creates the builtin user: admin. + + It is connected to the signal + openslides.core.signals.post_database_setup during app loading. """ # Check whether the group pks 1 to 4 are free if Group.objects.filter(pk__in=range(1, 5)).exists(): @@ -184,8 +182,12 @@ def create_builtin_groups_and_admin(sender, **kwargs): create_or_reset_admin_user() -@receiver(signals.post_save, sender=User) def user_post_save(sender, instance, *args, **kwargs): + """ + Receiver function to add a new user to the registered group. It is + connected to the signal django.db.models.signals.post_save during app + loading. + """ if not kwargs['created']: return diff --git a/openslides/users/slides.py b/openslides/users/slides.py deleted file mode 100644 index 1bdcfa892..000000000 --- a/openslides/users/slides.py +++ /dev/null @@ -1,5 +0,0 @@ -from openslides.projector.api import register_slide_model - -from .models import User - -register_slide_model(User, 'participant/user_slide.html')