Merge pull request #1369 from normanjaeckel/AppLoadingSystem

Added Django's application configuration.
This commit is contained in:
Norman Jäckel 2014-12-10 18:02:49 +01:00
commit ecdfa37173
40 changed files with 288 additions and 125 deletions

View File

@ -7,9 +7,13 @@ http://openslides.org
Version 2.0.0 (unreleased) Version 2.0.0 (unreleased)
========================== ==========================
- Changed supported Python version to >= 3.3 Other:
- Used Django 1.7 as lowest requirement - Changed supported Python version to >= 3.3.
- Refactoring of the participant app. Now called 'users' - 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) Version 1.6.1 (2014-12-08)

View File

@ -1 +1 @@
from . import widgets # noqa default_app_config = 'openslides.account.apps.AccountAppConfig'

View File

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

View File

@ -1 +1 @@
from . import main_menu, personal_info, signals, slides, widgets # noqa default_app_config = 'openslides.agenda.apps.AgendaAppConfig'

28
openslides/agenda/apps.py Normal file
View File

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

View File

@ -1,6 +1,6 @@
import re import re
from ckeditor.widgets import CKEditorWidget
from ckeditor.widgets import CKEditorWidget
from django import forms from django import forms
from django.utils.translation import ugettext_lazy from django.utils.translation import ugettext_lazy
from mptt.forms import TreeNodeChoiceField from mptt.forms import TreeNodeChoiceField

View File

@ -3,17 +3,13 @@ from datetime import datetime
from django import forms from django import forms
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ValidationError 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.template.loader import render_to_string
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.utils.translation import ugettext_lazy, ugettext_noop from django.utils.translation import ugettext_lazy, ugettext_noop
from openslides.config.api import config, ConfigCollection, ConfigVariable 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.api import get_active_slide, get_active_object
from openslides.projector.projector import Overlay from openslides.projector.projector import Overlay
from openslides.projector.signals import projector_overlays
from .models import Item from .models import Item
@ -27,10 +23,10 @@ def validate_start_time(value):
# TODO: Reinsert the datepicker scripts in the template # TODO: Reinsert the datepicker scripts in the template
@receiver(config_signal, dispatch_uid='setup_agenda_config')
def setup_agenda_config(sender, **kwargs): 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. # TODO: Insert validator for the format or use other field carefully.
agenda_start_event_date_time = ConfigVariable( agenda_start_event_date_time = ConfigVariable(
@ -94,10 +90,11 @@ def setup_agenda_config(sender, **kwargs):
'extra_javascript': extra_javascript}) 'extra_javascript': extra_javascript})
@receiver(projector_overlays, dispatch_uid="agenda_list_of_speakers")
def agenda_list_of_speakers(sender, **kwargs): 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' name = 'agenda_speaker'
@ -141,10 +138,11 @@ def agenda_list_of_speakers(sender, **kwargs):
return Overlay(name, get_widget_html, get_projector_html) return Overlay(name, get_widget_html, get_projector_html)
@receiver(pre_delete)
def listen_to_related_object_delete_signal(sender, instance, **kwargs): 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'): if hasattr(instance, 'get_agenda_title'):
for item in Item.objects.filter(content_type=ContentType.objects.get_for_model(sender), object_id=instance.pk): for item in Item.objects.filter(content_type=ContentType.objects.get_for_model(sender), object_id=instance.pk):

View File

@ -1,7 +1,7 @@
from django.template.loader import render_to_string from django.template.loader import render_to_string
from openslides.config.api import config 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 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 'summary', show a summary of all children of the item.
If 'type' is 'list_of_speakers', show the list of speakers for 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) item_pk = kwargs.get('pk', None)
slide_type = kwargs.get('type', None) slide_type = kwargs.get('type', None)
@ -56,6 +58,3 @@ def agenda_slide(**kwargs):
context = {'item': item} context = {'item': item}
slide = render_to_string('agenda/item_slide.html', context) slide = render_to_string('agenda/item_slide.html', context)
return slide return slide
register_slide('agenda', agenda_slide, Item)

View File

@ -1 +1 @@
# TODO: apploader default_app_config = 'openslides.assignment.apps.AssignmentAppConfig'

View File

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

View File

@ -342,7 +342,3 @@ class AssignmentPoll(SlideMixin, RelatedModelMixin, CollectDefaultVotesMixin,
def get_slide_context(self, **context): def get_slide_context(self, **context):
return super(AssignmentPoll, self).get_slide_context(poll=self) 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

View File

@ -1,17 +1,16 @@
from django import forms from django import forms
from django.dispatch import receiver
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.utils.translation import ugettext_lazy, ugettext_noop from django.utils.translation import ugettext_lazy, ugettext_noop
from openslides.config.api import ConfigGroup, ConfigGroupedCollection, ConfigVariable from openslides.config.api import ConfigGroup, ConfigGroupedCollection, ConfigVariable
from openslides.config.signals import config_signal
from openslides.poll.models import PERCENT_BASE_CHOICES from openslides.poll.models import PERCENT_BASE_CHOICES
@receiver(config_signal, dispatch_uid='setup_assignment_config')
def setup_assignment_config(sender, **kwargs): 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 # Ballot and ballot papers
assignment_poll_vote_values = ConfigVariable( assignment_poll_vote_values = ConfigVariable(

View File

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

View File

@ -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): 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') context['extra_stylefiles'].append('css/assignment.css')

View File

@ -1 +1 @@
from . import main_menu # noqa default_app_config = 'openslides.config.apps.ConfigAppConfig'

11
openslides/config/apps.py Normal file
View File

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

View File

@ -1 +1 @@
# TODO: apploading default_app_config = 'openslides.core.apps.CoreAppConfig'

23
openslides/core/apps.py Normal file
View File

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

View File

@ -44,7 +44,3 @@ class CustomSlide(SlideMixin, AbsoluteUrlMixin, models.Model):
else: else:
url = super(CustomSlide, self).get_absolute_url(link) url = super(CustomSlide, self).get_absolute_url(link)
return url return url
# TODO: apploader
from . import main_menu, signals, slides, widgets # noqa

View File

@ -1,20 +1,20 @@
from django import forms 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 as _
from django.utils.translation import ugettext_lazy, ugettext_noop from django.utils.translation import ugettext_lazy, ugettext_noop
from openslides.config.api import ConfigGroup, ConfigGroupedCollection, ConfigVariable from openslides.config.api import ConfigGroup, ConfigGroupedCollection, ConfigVariable
from openslides.config.signals import config_signal
from openslides.projector.api import update_projector from openslides.projector.api import update_projector
post_database_setup = Signal() post_database_setup = Signal()
@receiver(config_signal, dispatch_uid='setup_general_config')
def setup_general_config(sender, **kwargs): def setup_general_config(sender, **kwargs):
""" """
General config variables for OpenSlides. They are grouped in 'Event', Receiver function to setup general config variables for OpenSlides.
'Welcome Widget' and 'System'. 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( event_name = ConfigVariable(
name='event_name', name='event_name',

View File

@ -1,5 +0,0 @@
from openslides.projector.api import register_slide_model
from .models import CustomSlide
register_slide_model(CustomSlide, 'core/customslide_slide.html')

View File

@ -36,8 +36,11 @@ class CustonSlideWidget(Widget):
icon_css_class = 'icon-star' icon_css_class = 'icon-star'
def get_context_data(self, **context): def get_context_data(self, **context):
return super(CustonSlideWidget, self).get_context_data( """
slides=CustomSlide.objects.all().order_by('weight'), Adds custom slides and a flag whether the welcome page is active to
welcomepage_is_active=( the context.
get_active_slide().get('callback', 'default') == 'default'), """
**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)

View File

@ -1 +1 @@
from . import main_menu, slides, template, widgets # noqa default_app_config = 'openslides.mediafile.apps.MediafileAppConfig'

View File

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

View File

@ -1,9 +1,7 @@
#!/usr/bin/env python
from django.template.loader import render_to_string from django.template.loader import render_to_string
from openslides.config.api import config from openslides.config.api import config
from openslides.projector.api import register_slide, SlideError from openslides.projector.api import SlideError
from .models import Mediafile from .models import Mediafile
@ -13,6 +11,8 @@ def mediafile_presentation_as_slide(**kwargs):
Return the html code for a presentation of a Mediafile. Return the html code for a presentation of a Mediafile.
At the moment, only the presentation of pdfs is supported. At the moment, only the presentation of pdfs is supported.
The function is registered during app loading.
""" """
file_pk = kwargs.get('pk', None) file_pk = kwargs.get('pk', None)
page_num = kwargs.get('page_num', 1) page_num = kwargs.get('page_num', 1)
@ -27,6 +27,3 @@ def mediafile_presentation_as_slide(**kwargs):
context = {'pdf': pdf, 'page_num': page_num, context = {'pdf': pdf, 'page_num': page_num,
'fullscreen': config['pdf_fullscreen']} 'fullscreen': config['pdf_fullscreen']}
return render_to_string('mediafile/presentation_slide.html', context) return render_to_string('mediafile/presentation_slide.html', context)
register_slide('mediafile', mediafile_presentation_as_slide, Mediafile)

View File

@ -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): 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') context['extra_stylefiles'].append('css/mediafile.css')

View File

@ -1 +1 @@
# TODO: Apploading default_app_config = 'openslides.motion.apps.MotionAppConfig'

27
openslides/motion/apps.py Normal file
View File

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

View File

@ -852,7 +852,3 @@ class Workflow(models.Model):
raise WorkflowError( raise WorkflowError(
'%s can not be first state of %s because it ' '%s can not be first state of %s because it '
'does not belong to it.' % (self.first_state, self)) 'does not belong to it.' % (self.first_state, self))
# TODO: Apploading
from . import main_menu, personal_info, signals, slides, widgets # noqa

View File

@ -1,20 +1,17 @@
from django import forms from django import forms
from django.dispatch import receiver
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.utils.translation import ugettext_lazy, ugettext_noop from django.utils.translation import ugettext_lazy, ugettext_noop
from openslides.config.api import ConfigGroup, ConfigGroupedCollection, ConfigVariable 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 openslides.poll.models import PERCENT_BASE_CHOICES
from .models import State, Workflow from .models import State, Workflow
@receiver(config_signal, dispatch_uid='setup_motion_config')
def setup_motion_config(sender, **kwargs): 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 # General
motion_workflow = ConfigVariable( motion_workflow = ConfigVariable(
@ -149,10 +146,11 @@ def setup_motion_config(sender, **kwargs):
groups=(group_general, group_supporters, group_ballot_papers, group_pdf)) 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): 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')) workflow_1, created = Workflow.objects.get_or_create(name=ugettext_noop('Simple Workflow'))
if created: if created:

View File

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

View File

@ -0,0 +1,2 @@
# This app uses Django's base AppConfig class so the variable
# default_app_config is not defined.

View File

@ -1 +1 @@
from . import signals, widgets # noqa default_app_config = 'openslides.projector.apps.ProjectorAppConfig'

View File

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

View File

@ -1,6 +1,5 @@
import warnings import warnings
from openslides.config.api import config from openslides.config.api import config
from .exceptions import ProjectorExceptionWarning from .exceptions import ProjectorExceptionWarning

View File

@ -2,23 +2,22 @@ from time import time
from django.contrib.staticfiles.templatetags.staticfiles import static from django.contrib.staticfiles.templatetags.staticfiles import static
from django.core.context_processors import csrf 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.template.loader import render_to_string
from django.utils.datastructures import SortedDict from django.utils.datastructures import SortedDict
from openslides.config.api import config, ConfigCollection, ConfigVariable from openslides.config.api import config, ConfigCollection, ConfigVariable
from openslides.config.signals import config_signal
from .projector import Overlay from .projector import Overlay
projector_overlays = Signal(providing_args=['request']) projector_overlays = Signal(providing_args=['request'])
@receiver(config_signal, dispatch_uid='setup_projector_config')
def setup_projector_config(sender, **kwargs): def setup_projector_config(sender, **kwargs):
""" """
Projector config variables for OpenSlides. They are not shown on a Receiver function to setup all projector config variables. They are not
config view. 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 # The active slide. The config-value is a dictonary with at least the entry
# 'callback'. # 'callback'.
@ -75,10 +74,10 @@ def setup_projector_config(sender, **kwargs):
projector_pdf_fullscreen)) projector_pdf_fullscreen))
@receiver(projector_overlays, dispatch_uid="projector_countdown")
def countdown(sender, **kwargs): 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' name = 'projector_countdown'
request = kwargs.get('request', None) 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) 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): def projector_overlay_message(sender, **kwargs):
""" """
Receiver to show the overlay_message on the projector or the form in the Receiver function to show the overlay_message on the projector or the
overlay-widget on the dashboard. form in the overlay-widget on the dashboard. The function is connected
to the signal projector_overlays during app loading.
""" """
name = 'projector_message' name = 'projector_message'
request = kwargs.get('request', None) request = kwargs.get('request', None)
@ -143,10 +142,10 @@ def projector_overlay_message(sender, **kwargs):
return Overlay(name, get_widget_html, get_projector_html) return Overlay(name, get_widget_html, get_projector_html)
@receiver(projector_overlays, dispatch_uid="projector_clock")
def projector_clock(sender, **kwargs): 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' name = 'projector_clock'

View File

@ -1 +1 @@
from . import main_menu, signals, slides, widgets # noqa default_app_config = 'openslides.users.apps.UsersAppConfig'

29
openslides/users/apps.py Normal file
View File

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

View File

@ -1,23 +1,19 @@
from django import forms from django import forms
from django.contrib.auth.models import Permission from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType 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 as _
from django.utils.translation import ugettext_lazy, ugettext_noop 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.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 .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): 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 # General
users_sort_users_by_first_name = ConfigVariable( users_sort_users_by_first_name = ConfigVariable(
@ -108,14 +104,16 @@ def setup_users_config(sender, **kwargs):
groups=(group_general, group_pdf)) 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): 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 groups: Anonymous, Registered, Delegates and Staff.
Creates the builtin user: admin. 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 # Check whether the group pks 1 to 4 are free
if Group.objects.filter(pk__in=range(1, 5)).exists(): 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() create_or_reset_admin_user()
@receiver(signals.post_save, sender=User)
def user_post_save(sender, instance, *args, **kwargs): 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']: if not kwargs['created']:
return return

View File

@ -1,5 +0,0 @@
from openslides.projector.api import register_slide_model
from .models import User
register_slide_model(User, 'participant/user_slide.html')