clean up the projector App
This commit is contained in:
parent
eb3adcd8ca
commit
15621b7702
@ -17,6 +17,9 @@ from openslides.projector.projector import SLIDE, Slide, Widget
|
|||||||
|
|
||||||
|
|
||||||
def split_sid(sid):
|
def split_sid(sid):
|
||||||
|
"""
|
||||||
|
Slit a SID in the model-part and in the model-id
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
data = sid.split('-')
|
data = sid.split('-')
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
@ -34,6 +37,11 @@ def split_sid(sid):
|
|||||||
|
|
||||||
|
|
||||||
def get_slide_from_sid(sid, element=False):
|
def get_slide_from_sid(sid, element=False):
|
||||||
|
"""
|
||||||
|
Return the Slide for an given sid.
|
||||||
|
If element== False, return the slide-dict,
|
||||||
|
else, return the object.
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
key, id = split_sid(sid)
|
key, id = split_sid(sid)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
@ -56,10 +64,10 @@ def get_slide_from_sid(sid, element=False):
|
|||||||
def get_active_slide(only_sid=False):
|
def get_active_slide(only_sid=False):
|
||||||
"""
|
"""
|
||||||
Returns the active slide. If no slide is active, or it can not find an Item,
|
Returns the active slide. If no slide is active, or it can not find an Item,
|
||||||
it raise an error
|
return None
|
||||||
|
|
||||||
if only_sid is True, returns only the id of this item. Returns None if not Item
|
if only_sid is True, returns only the id of this item. Returns None if not
|
||||||
is active. Does not Raise Item.DoesNotExist
|
Item is active.
|
||||||
"""
|
"""
|
||||||
sid = config["presentation"]
|
sid = config["presentation"]
|
||||||
|
|
||||||
@ -69,12 +77,18 @@ def get_active_slide(only_sid=False):
|
|||||||
|
|
||||||
|
|
||||||
def set_active_slide(sid, argument=None):
|
def set_active_slide(sid, argument=None):
|
||||||
|
"""
|
||||||
|
Set the active Slide.
|
||||||
|
"""
|
||||||
config["presentation"] = sid
|
config["presentation"] = sid
|
||||||
config['presentation_argument'] = argument
|
config['presentation_argument'] = argument
|
||||||
|
|
||||||
|
|
||||||
def register_slidemodel(model, model_name=None, control_template=None, weight=0):
|
def register_slidemodel(model, model_name=None, control_template=None,
|
||||||
#TODO: Warn if there already is a slide with this prefix
|
weight=0):
|
||||||
|
"""
|
||||||
|
Register a Model as a slide.
|
||||||
|
"""
|
||||||
if model_name is None:
|
if model_name is None:
|
||||||
model_name = model.prefix
|
model_name = model.prefix
|
||||||
|
|
||||||
@ -94,7 +108,9 @@ def register_slidemodel(model, model_name=None, control_template=None, weight=0)
|
|||||||
|
|
||||||
|
|
||||||
def register_slidefunc(key, func, control_template=None, weight=0, name=''):
|
def register_slidefunc(key, func, control_template=None, weight=0, name=''):
|
||||||
#TODO: Warn if there already is a slide with this prefix
|
"""
|
||||||
|
Register a function for as a slide.
|
||||||
|
"""
|
||||||
if control_template is None:
|
if control_template is None:
|
||||||
control_template = 'projector/default_control_slidefunc.html'
|
control_template = 'projector/default_control_slidefunc.html'
|
||||||
category = func.__module__.split('.')[0]
|
category = func.__module__.split('.')[0]
|
||||||
@ -110,6 +126,10 @@ def register_slidefunc(key, func, control_template=None, weight=0, name=''):
|
|||||||
|
|
||||||
|
|
||||||
def projector_message_set(message, sid=None):
|
def projector_message_set(message, sid=None):
|
||||||
|
"""
|
||||||
|
Set the overlay-message.
|
||||||
|
if sid is set, only show the message on the sid-slide.
|
||||||
|
"""
|
||||||
from models import ProjectorOverlay
|
from models import ProjectorOverlay
|
||||||
config['projector_message'] = message
|
config['projector_message'] = message
|
||||||
try:
|
try:
|
||||||
@ -121,4 +141,7 @@ def projector_message_set(message, sid=None):
|
|||||||
|
|
||||||
|
|
||||||
def projector_message_delete():
|
def projector_message_delete():
|
||||||
|
"""
|
||||||
|
Delete the overlay-message.
|
||||||
|
"""
|
||||||
config['projector_message'] = ''
|
config['projector_message'] = ''
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
openslides.projector.models
|
openslides.projector.models
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Models for the projector app.
|
Models for the projector app.
|
||||||
|
|
||||||
@ -12,22 +12,25 @@
|
|||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
|
from django.utils.translation import ugettext as _, ugettext_noop
|
||||||
|
|
||||||
from openslides.config.signals import default_config_value
|
from openslides.config.signals import default_config_value
|
||||||
|
|
||||||
from api import register_slidemodel
|
from openslides.projector.api import register_slidemodel
|
||||||
from projector import SlideMixin
|
from openslides.projector.projector import SlideMixin
|
||||||
|
|
||||||
|
from openslides.config.models import config
|
||||||
|
|
||||||
from config.models import config
|
|
||||||
from utils.translation_ext import ugettext as _
|
|
||||||
|
|
||||||
|
|
||||||
class ProjectorSlide(models.Model, SlideMixin):
|
class ProjectorSlide(models.Model, SlideMixin):
|
||||||
|
"""
|
||||||
|
Model for Slides, only for the projector. Also called custom slides.
|
||||||
|
"""
|
||||||
prefix = 'ProjectorSlide'
|
prefix = 'ProjectorSlide'
|
||||||
|
|
||||||
title = models.CharField(max_length=256, verbose_name=_("Title"))
|
title = models.CharField(max_length=256, verbose_name=_("Title"))
|
||||||
text = models.TextField(null=True, blank=True, verbose_name=_("Text"))
|
text = models.TextField(null=True, blank=True, verbose_name=_("Text"))
|
||||||
#weight = models.IntegerField(default=0, verbose_name=_("Weight"))
|
|
||||||
|
|
||||||
def slide(self):
|
def slide(self):
|
||||||
return {
|
return {
|
||||||
@ -46,12 +49,19 @@ class ProjectorSlide(models.Model, SlideMixin):
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
permissions = (
|
permissions = (
|
||||||
('can_manage_projector', _("Can manage the projector", fixstr=True)),
|
('can_manage_projector', ugettext_noop("Can manage the projector")),
|
||||||
('can_see_projector', _("Can see projector", fixstr=True)),
|
('can_see_projector', ugettext_noop("Can see projector")),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
register_slidemodel(ProjectorSlide,
|
||||||
|
control_template='projector/control_customslide.html')
|
||||||
|
|
||||||
|
|
||||||
class ProjectorOverlay(models.Model):
|
class ProjectorOverlay(models.Model):
|
||||||
|
"""
|
||||||
|
Save information for a overlay.
|
||||||
|
"""
|
||||||
active = models.BooleanField(verbose_name=_('Active'))
|
active = models.BooleanField(verbose_name=_('Active'))
|
||||||
def_name = models.CharField(max_length=64)
|
def_name = models.CharField(max_length=64)
|
||||||
sid = models.CharField(max_length=64, null=True, blank=True)
|
sid = models.CharField(max_length=64, null=True, blank=True)
|
||||||
@ -62,9 +72,6 @@ class ProjectorOverlay(models.Model):
|
|||||||
return self.def_name
|
return self.def_name
|
||||||
|
|
||||||
|
|
||||||
register_slidemodel(ProjectorSlide, control_template='projector/control_customslide.html')
|
|
||||||
|
|
||||||
|
|
||||||
@receiver(default_config_value, dispatch_uid="projector_default_config")
|
@receiver(default_config_value, dispatch_uid="projector_default_config")
|
||||||
def default_config(sender, key, **kwargs):
|
def default_config(sender, key, **kwargs):
|
||||||
return {
|
return {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
openslides.projector.projector
|
openslides.projector.projector
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Slide functions for the projector app.
|
Slide functions for the projector app.
|
||||||
|
|
||||||
@ -29,7 +29,7 @@ class SlideMixin(object):
|
|||||||
|
|
||||||
def slide(self):
|
def slide(self):
|
||||||
"""
|
"""
|
||||||
Return a map with all Data for a Slide
|
Return a map with all Data for the Slide.
|
||||||
"""
|
"""
|
||||||
return {
|
return {
|
||||||
'slide': self,
|
'slide': self,
|
||||||
@ -47,19 +47,22 @@ class SlideMixin(object):
|
|||||||
@property
|
@property
|
||||||
def active(self):
|
def active(self):
|
||||||
"""
|
"""
|
||||||
Return True, if the the slide is the active one.
|
Return True, if the the slide is the active slide.
|
||||||
"""
|
"""
|
||||||
from api import get_active_slide
|
from api import get_active_slide
|
||||||
return True if get_active_slide(only_sid=True) == self.sid else False
|
return get_active_slide(only_sid=True) == self.sid
|
||||||
|
|
||||||
def set_active(self):
|
def set_active(self):
|
||||||
"""
|
"""
|
||||||
Appoint this item as the active one.
|
Appoint this item as the active slide.
|
||||||
"""
|
"""
|
||||||
config["presentation"] = "%s-%d" % (self.prefix, self.id)
|
set_active_slide(self.sid)
|
||||||
|
|
||||||
|
|
||||||
class Slide(object):
|
class Slide(object):
|
||||||
|
"""
|
||||||
|
Represents a Slide for the projector. Can be a modelinstanz, or a function.
|
||||||
|
"""
|
||||||
def __init__(self, model_slide=False, func=None, model=None, category=None,
|
def __init__(self, model_slide=False, func=None, model=None, category=None,
|
||||||
key=None, model_name='', control_template='', weight=0, name=''):
|
key=None, model_name='', control_template='', weight=0, name=''):
|
||||||
"""
|
"""
|
||||||
@ -82,10 +85,16 @@ class Slide(object):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def active(self):
|
def active(self):
|
||||||
|
"""
|
||||||
|
Return True if the Slide is active, else: False.
|
||||||
|
"""
|
||||||
from api import get_active_slide
|
from api import get_active_slide
|
||||||
return get_active_slide(True) == self.key
|
return get_active_slide(True) == self.key
|
||||||
|
|
||||||
def get_items(self):
|
def get_items(self):
|
||||||
|
"""
|
||||||
|
If the Slide is a Slide from a Model, return all Objects.
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
return self.model.objects.all()
|
return self.model.objects.all()
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
@ -93,6 +102,9 @@ class Slide(object):
|
|||||||
|
|
||||||
|
|
||||||
class Widget(object):
|
class Widget(object):
|
||||||
|
"""
|
||||||
|
Class for a Widget for the Projector-Tab.
|
||||||
|
"""
|
||||||
def __init__(self, name, html=None, template=None, context={}):
|
def __init__(self, name, html=None, template=None, context={}):
|
||||||
self.name = name
|
self.name = name
|
||||||
if html is not None:
|
if html is not None:
|
||||||
|
@ -13,5 +13,3 @@
|
|||||||
from django.dispatch import Signal
|
from django.dispatch import Signal
|
||||||
|
|
||||||
projector_overlays = Signal(providing_args=['register', 'call'])
|
projector_overlays = Signal(providing_args=['register', 'call'])
|
||||||
|
|
||||||
projector_control_box = Signal()
|
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""
|
|
||||||
openslides.projector.tests
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Unit tests for the projector app.
|
|
||||||
|
|
||||||
:copyright: 2011, 2012 by OpenSlides team, see AUTHORS.
|
|
||||||
:license: GNU GPL, see LICENSE for more details.
|
|
||||||
"""
|
|
||||||
|
|
||||||
from django.test import TestCase
|
|
||||||
|
|
||||||
|
|
||||||
class SimpleTest(TestCase):
|
|
||||||
def test_basic_addition(self):
|
|
||||||
"""
|
|
||||||
Tests that 1 + 1 always equals 2.
|
|
||||||
"""
|
|
||||||
self.assertEqual(1 + 1, 2)
|
|
@ -2,7 +2,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
openslides.projector.urls
|
openslides.projector.urls
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
URL list for the projector app.
|
URL list for the projector app.
|
||||||
|
|
||||||
@ -10,11 +10,8 @@
|
|||||||
:license: GNU GPL, see LICENSE for more details.
|
:license: GNU GPL, see LICENSE for more details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from django.conf.urls.defaults import *
|
from django.conf.urls.defaults import patterns, url
|
||||||
|
|
||||||
from openslides.utils.views import CreateView
|
|
||||||
|
|
||||||
from openslides.projector.models import ProjectorSlide
|
|
||||||
from openslides.projector.views import (ControlView, ActivateView,
|
from openslides.projector.views import (ControlView, ActivateView,
|
||||||
CustomSlideCreateView, CustomSlideUpdateView, CustomSlideDeleteView,
|
CustomSlideCreateView, CustomSlideUpdateView, CustomSlideDeleteView,
|
||||||
CountdownEdit, ProjectorEdit, Projector, ActivateOverlay)
|
CountdownEdit, ProjectorEdit, Projector, ActivateOverlay)
|
||||||
@ -104,12 +101,6 @@ urlpatterns = patterns('projector.views',
|
|||||||
name='projector_clean',
|
name='projector_clean',
|
||||||
),
|
),
|
||||||
|
|
||||||
# TODO: Merge the following lines with this one:
|
|
||||||
## url(r'^countdown/(?P<command>[^/]*)/$',
|
|
||||||
## CountdownEdit.as_view(),
|
|
||||||
## name='countdown_edit',
|
|
||||||
## ),
|
|
||||||
|
|
||||||
url(r'^countdown/reset/$',
|
url(r'^countdown/reset/$',
|
||||||
CountdownEdit.as_view(),
|
CountdownEdit.as_view(),
|
||||||
{'command': 'reset'},
|
{'command': 'reset'},
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
openslides.projector.views
|
openslides.projector.views
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Views for the projector app.
|
Views for the projector app.
|
||||||
|
|
||||||
@ -13,41 +13,48 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from time import time
|
from time import time
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.utils.translation import ugettext as _
|
from django.db.models import Q
|
||||||
|
from django.dispatch import receiver
|
||||||
from django.utils.datastructures import SortedDict
|
from django.utils.datastructures import SortedDict
|
||||||
from django.utils.importlib import import_module
|
from django.utils.importlib import import_module
|
||||||
from django.dispatch import receiver
|
from django.utils.translation import ugettext as _
|
||||||
from django.db.models import Q
|
|
||||||
from django.conf import settings
|
|
||||||
|
|
||||||
|
from openslides.utils.template import render_block_to_string, Tab
|
||||||
|
from openslides.utils.utils import html_strong
|
||||||
from openslides.utils.views import (TemplateView, RedirectView, CreateView,
|
from openslides.utils.views import (TemplateView, RedirectView, CreateView,
|
||||||
UpdateView, DeleteView, AjaxMixin)
|
UpdateView, DeleteView, AjaxMixin)
|
||||||
from openslides.utils.template import render_block_to_string, Tab
|
|
||||||
|
|
||||||
from openslides.config.models import config
|
from openslides.config.models import config
|
||||||
|
|
||||||
from openslides.projector.api import (get_active_slide, set_active_slide,
|
from openslides.projector.api import (get_active_slide, set_active_slide,
|
||||||
projector_message_set, projector_message_delete, get_slide_from_sid)
|
projector_message_set, projector_message_delete, get_slide_from_sid)
|
||||||
from openslides.projector.projector import SLIDE, Widget
|
|
||||||
from openslides.projector.models import ProjectorOverlay, ProjectorSlide
|
from openslides.projector.models import ProjectorOverlay, ProjectorSlide
|
||||||
|
from openslides.projector.projector import SLIDE, Widget
|
||||||
from openslides.projector.signals import projector_overlays
|
from openslides.projector.signals import projector_overlays
|
||||||
|
|
||||||
|
|
||||||
class ControlView(TemplateView, AjaxMixin):
|
class ControlView(TemplateView, AjaxMixin):
|
||||||
|
"""
|
||||||
|
Overview over all possible slides, the overlays and a liveview.
|
||||||
|
"""
|
||||||
template_name = 'projector/control.html'
|
template_name = 'projector/control.html'
|
||||||
permission_required = 'projector.can_manage_projector'
|
permission_required = 'projector.can_manage_projector'
|
||||||
|
|
||||||
def get_projector_overlays(self):
|
def get_projector_overlays(self):
|
||||||
overlays = []
|
overlays = []
|
||||||
for receiver, name in projector_overlays.send(sender='registerer', register=True):
|
for receiver, name in projector_overlays.send(sender='registerer',
|
||||||
|
register=True):
|
||||||
if name is not None:
|
if name is not None:
|
||||||
try:
|
try:
|
||||||
projector_overlay = ProjectorOverlay.objects.get(def_name=name)
|
projector_overlay = ProjectorOverlay.objects.get(
|
||||||
|
def_name=name)
|
||||||
except ProjectorOverlay.DoesNotExist:
|
except ProjectorOverlay.DoesNotExist:
|
||||||
active = name == 'Message'
|
active = name == 'Message'
|
||||||
projector_overlay = ProjectorOverlay(def_name=name, active=active)
|
projector_overlay = ProjectorOverlay(def_name=name,
|
||||||
|
active=active)
|
||||||
projector_overlay.save()
|
projector_overlay.save()
|
||||||
overlays.append(projector_overlay)
|
overlays.append(projector_overlay)
|
||||||
return overlays
|
return overlays
|
||||||
@ -57,13 +64,6 @@ class ControlView(TemplateView, AjaxMixin):
|
|||||||
projector_message_set(request.POST['message_text'])
|
projector_message_set(request.POST['message_text'])
|
||||||
elif 'message-clean' in request.POST:
|
elif 'message-clean' in request.POST:
|
||||||
projector_message_delete()
|
projector_message_delete()
|
||||||
else:
|
|
||||||
for overlay in self.get_projector_overlays():
|
|
||||||
if overlay.def_name in request.POST:
|
|
||||||
overlay.active = True
|
|
||||||
else:
|
|
||||||
overlay.active = False
|
|
||||||
overlay.save()
|
|
||||||
if request.is_ajax():
|
if request.is_ajax():
|
||||||
return self.ajax_get(request, *args, **kwargs)
|
return self.ajax_get(request, *args, **kwargs)
|
||||||
return self.get(request, *args, **kwargs)
|
return self.get(request, *args, **kwargs)
|
||||||
@ -101,87 +101,10 @@ class ControlView(TemplateView, AjaxMixin):
|
|||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
class ActivateOverlay(RedirectView):
|
|
||||||
url = 'projector_control'
|
|
||||||
allow_ajax = True
|
|
||||||
|
|
||||||
@property
|
|
||||||
def overlay(self):
|
|
||||||
try:
|
|
||||||
return self._overlay
|
|
||||||
except AttributeError:
|
|
||||||
self._overlay = ProjectorOverlay.objects.get(def_name=self.kwargs['name'])
|
|
||||||
return self._overlay
|
|
||||||
|
|
||||||
def pre_redirect(self, request, *args, **kwargs):
|
|
||||||
if kwargs['activate']:
|
|
||||||
self.overlay.active = True
|
|
||||||
else:
|
|
||||||
self.overlay.active = False
|
|
||||||
self.overlay.save()
|
|
||||||
|
|
||||||
def get_ajax_context(self, **kwargs):
|
|
||||||
return {
|
|
||||||
'active': self.overlay.active,
|
|
||||||
'def_name': self.overlay.def_name,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class ActivateView(RedirectView):
|
|
||||||
url = 'projector_control'
|
|
||||||
allow_ajax = True
|
|
||||||
|
|
||||||
def pre_redirect(self, request, *args, **kwargs):
|
|
||||||
try:
|
|
||||||
set_active_slide(kwargs['sid'], kwargs['argument'])
|
|
||||||
except KeyError:
|
|
||||||
set_active_slide(kwargs['sid'])
|
|
||||||
config['up'] = 0
|
|
||||||
config['bigger'] = 100
|
|
||||||
|
|
||||||
|
|
||||||
class CustomSlideCreateView(CreateView):
|
|
||||||
permission_required = 'agenda.can_manage_agenda'
|
|
||||||
template_name = 'projector/new.html'
|
|
||||||
model = ProjectorSlide
|
|
||||||
context_object_name = 'customslide'
|
|
||||||
success_url = 'projector_control'
|
|
||||||
apply_url = 'customslide_edit'
|
|
||||||
|
|
||||||
def get_success_url(self):
|
|
||||||
messages.success(self.request, _("Custom slide <b>%s</b> was successfully created.") % self.request.POST['title'])
|
|
||||||
if 'apply' in self.request.POST:
|
|
||||||
return reverse(self.get_apply_url(), args=[self.object.id])
|
|
||||||
return reverse(super(CreateView, self).get_success_url())
|
|
||||||
|
|
||||||
|
|
||||||
class CustomSlideUpdateView(UpdateView):
|
|
||||||
permission_required = 'projector.can_manage_projector'
|
|
||||||
template_name = 'projector/new.html'
|
|
||||||
model = ProjectorSlide
|
|
||||||
context_object_name = 'customslide'
|
|
||||||
success_url = 'projector_control'
|
|
||||||
apply_url = 'customslide_edit'
|
|
||||||
|
|
||||||
def get_success_url(self):
|
|
||||||
messages.success(self.request, _("Custom slide <b>%s</b> was successfully modified.") % self.request.POST['title'])
|
|
||||||
if 'apply' in self.request.POST:
|
|
||||||
return ''
|
|
||||||
return reverse(super(UpdateView, self).get_success_url())
|
|
||||||
|
|
||||||
|
|
||||||
class CustomSlideDeleteView(DeleteView):
|
|
||||||
permission_required = 'projector.can_manage_projector'
|
|
||||||
model = ProjectorSlide
|
|
||||||
url = 'projector_control'
|
|
||||||
|
|
||||||
def pre_post_redirect(self, request, *args, **kwargs):
|
|
||||||
self.object = self.get_object()
|
|
||||||
self.object.delete()
|
|
||||||
messages.success(request, _("Custom slide <b>%s</b> was successfully deleted.") % self.object)
|
|
||||||
|
|
||||||
|
|
||||||
class Projector(TemplateView, AjaxMixin):
|
class Projector(TemplateView, AjaxMixin):
|
||||||
|
"""
|
||||||
|
The Projector-Page.
|
||||||
|
"""
|
||||||
permission_required = 'projector.can_see_projector'
|
permission_required = 'projector.can_see_projector'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -211,8 +134,11 @@ class Projector(TemplateView, AjaxMixin):
|
|||||||
|
|
||||||
# Projector Overlays
|
# Projector Overlays
|
||||||
if self.kwargs['sid'] is None:
|
if self.kwargs['sid'] is None:
|
||||||
active_defs = ProjectorOverlay.objects.filter(active=True).filter(Q(sid=sid) | Q(sid=None)).values_list('def_name', flat=True)
|
active_defs = ProjectorOverlay.objects.filter(active=True) \
|
||||||
for receiver, response in projector_overlays.send(sender=sid, register=False, call=active_defs):
|
.filter(Q(sid=sid) | Q(sid=None)).values_list('def_name',
|
||||||
|
flat=True)
|
||||||
|
for receiver, response in projector_overlays.send(sender=sid,
|
||||||
|
register=False, call=active_defs):
|
||||||
if response is not None:
|
if response is not None:
|
||||||
data['overlays'].append(response)
|
data['overlays'].append(response)
|
||||||
self._data = data
|
self._data = data
|
||||||
@ -227,8 +153,10 @@ class Projector(TemplateView, AjaxMixin):
|
|||||||
return context
|
return context
|
||||||
|
|
||||||
def get_ajax_context(self, **kwargs):
|
def get_ajax_context(self, **kwargs):
|
||||||
content = render_block_to_string(self.get_template_names()[0], 'content', self.data)
|
content = render_block_to_string(self.get_template_names()[0],
|
||||||
scrollcontent = render_block_to_string(self.get_template_names()[0], 'scrollcontent', self.data)
|
'content', self.data)
|
||||||
|
scrollcontent = render_block_to_string(self.get_template_names()[0],
|
||||||
|
'scrollcontent', self.data)
|
||||||
|
|
||||||
context = super(Projector, self).get_ajax_context(**kwargs)
|
context = super(Projector, self).get_ajax_context(**kwargs)
|
||||||
content_hash = hash(content)
|
content_hash = hash(content)
|
||||||
@ -250,8 +178,27 @@ class Projector(TemplateView, AjaxMixin):
|
|||||||
return super(Projector, self).get(request, *args, **kwargs)
|
return super(Projector, self).get(request, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class ActivateView(RedirectView):
|
||||||
|
"""
|
||||||
|
Activate a Slide.
|
||||||
|
"""
|
||||||
|
permission_required = 'projector.can_manage_projector'
|
||||||
|
url = 'projector_control'
|
||||||
|
allow_ajax = True
|
||||||
|
|
||||||
|
def pre_redirect(self, request, *args, **kwargs):
|
||||||
|
try:
|
||||||
|
set_active_slide(kwargs['sid'], kwargs['argument'])
|
||||||
|
except KeyError:
|
||||||
|
set_active_slide(kwargs['sid'])
|
||||||
|
config['up'] = 0
|
||||||
|
config['bigger'] = 100
|
||||||
|
|
||||||
|
|
||||||
class ProjectorEdit(RedirectView):
|
class ProjectorEdit(RedirectView):
|
||||||
|
"""
|
||||||
|
Scale or scroll the projector.
|
||||||
|
"""
|
||||||
permission_required = 'projector.can_manage_projector'
|
permission_required = 'projector.can_manage_projector'
|
||||||
url = 'projector_control'
|
url = 'projector_control'
|
||||||
allow_ajax = True
|
allow_ajax = True
|
||||||
@ -273,6 +220,9 @@ class ProjectorEdit(RedirectView):
|
|||||||
|
|
||||||
|
|
||||||
class CountdownEdit(RedirectView):
|
class CountdownEdit(RedirectView):
|
||||||
|
"""
|
||||||
|
Start, stop or reset the countdown.
|
||||||
|
"""
|
||||||
permission_required = 'projector.can_manage_projector'
|
permission_required = 'projector.can_manage_projector'
|
||||||
url = 'projector_control'
|
url = 'projector_control'
|
||||||
allow_ajax = True
|
allow_ajax = True
|
||||||
@ -293,8 +243,8 @@ class CountdownEdit(RedirectView):
|
|||||||
start_stamp = config['countdown_start_stamp']
|
start_stamp = config['countdown_start_stamp']
|
||||||
pause_stamp = config['countdown_pause_stamp']
|
pause_stamp = config['countdown_pause_stamp']
|
||||||
now = time()
|
now = time()
|
||||||
|
config['countdown_start_stamp'] = now - \
|
||||||
config['countdown_start_stamp'] = now - (pause_stamp - start_stamp)
|
(pause_stamp - start_stamp)
|
||||||
else:
|
else:
|
||||||
config['countdown_start_stamp'] = time()
|
config['countdown_start_stamp'] = time()
|
||||||
|
|
||||||
@ -306,7 +256,8 @@ class CountdownEdit(RedirectView):
|
|||||||
config['countdown_state'] = 'paused'
|
config['countdown_state'] = 'paused'
|
||||||
elif command == 'set-default':
|
elif command == 'set-default':
|
||||||
try:
|
try:
|
||||||
config['countdown_time'] = int(self.request.GET['countdown_time'])
|
config['countdown_time'] = \
|
||||||
|
int(self.request.GET['countdown_time'])
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
@ -319,7 +270,74 @@ class CountdownEdit(RedirectView):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class ActivateOverlay(RedirectView):
|
||||||
|
"""
|
||||||
|
Activate or deactivate an overlay.
|
||||||
|
"""
|
||||||
|
url = 'projector_control'
|
||||||
|
allow_ajax = True
|
||||||
|
permission_required = 'projector.can_manage_projector'
|
||||||
|
|
||||||
|
@property
|
||||||
|
def overlay(self):
|
||||||
|
try:
|
||||||
|
return self._overlay
|
||||||
|
except AttributeError:
|
||||||
|
self._overlay = ProjectorOverlay.objects.get(
|
||||||
|
def_name=self.kwargs['name'])
|
||||||
|
return self._overlay
|
||||||
|
|
||||||
|
def pre_redirect(self, request, *args, **kwargs):
|
||||||
|
if kwargs['activate']:
|
||||||
|
self.overlay.active = True
|
||||||
|
else:
|
||||||
|
self.overlay.active = False
|
||||||
|
self.overlay.save()
|
||||||
|
|
||||||
|
def get_ajax_context(self, **kwargs):
|
||||||
|
return {
|
||||||
|
'active': self.overlay.active,
|
||||||
|
'def_name': self.overlay.def_name,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class CustomSlideCreateView(CreateView):
|
||||||
|
"""
|
||||||
|
Create a custom slide.
|
||||||
|
"""
|
||||||
|
permission_required = 'agenda.can_manage_agenda'
|
||||||
|
template_name = 'projector/new.html'
|
||||||
|
model = ProjectorSlide
|
||||||
|
context_object_name = 'customslide'
|
||||||
|
success_url = 'projector_control'
|
||||||
|
apply_url = 'customslide_edit'
|
||||||
|
|
||||||
|
|
||||||
|
class CustomSlideUpdateView(UpdateView):
|
||||||
|
"""
|
||||||
|
Update a custom slide.
|
||||||
|
"""
|
||||||
|
permission_required = 'projector.can_manage_projector'
|
||||||
|
template_name = 'projector/new.html'
|
||||||
|
model = ProjectorSlide
|
||||||
|
context_object_name = 'customslide'
|
||||||
|
success_url = 'projector_control'
|
||||||
|
apply_url = 'customslide_edit'
|
||||||
|
|
||||||
|
|
||||||
|
class CustomSlideDeleteView(DeleteView):
|
||||||
|
"""
|
||||||
|
Delete a custom slide.
|
||||||
|
"""
|
||||||
|
permission_required = 'projector.can_manage_projector'
|
||||||
|
model = ProjectorSlide
|
||||||
|
url = 'projector_control'
|
||||||
|
|
||||||
|
|
||||||
def register_tab(request):
|
def register_tab(request):
|
||||||
|
"""
|
||||||
|
Register the projector tab.
|
||||||
|
"""
|
||||||
selected = True if request.path.startswith('/projector/') else False
|
selected = True if request.path.startswith('/projector/') else False
|
||||||
return Tab(
|
return Tab(
|
||||||
title=_('Projector'),
|
title=_('Projector'),
|
||||||
@ -330,6 +348,9 @@ def register_tab(request):
|
|||||||
|
|
||||||
|
|
||||||
def get_widgets(request):
|
def get_widgets(request):
|
||||||
|
"""
|
||||||
|
Return the custom slide widget.
|
||||||
|
"""
|
||||||
return [
|
return [
|
||||||
Widget(
|
Widget(
|
||||||
name='projector',
|
name='projector',
|
||||||
|
@ -52,7 +52,7 @@ from django.views.generic.list import TemplateResponseMixin
|
|||||||
|
|
||||||
from openslides.config.models import config
|
from openslides.config.models import config
|
||||||
|
|
||||||
from openslides.utils.utils import render_to_forbitten
|
from openslides.utils.utils import render_to_forbitten, html_strong
|
||||||
from openslides.utils.signals import template_manipulation
|
from openslides.utils.signals import template_manipulation
|
||||||
from openslides.utils.pdf import firstPage, laterPages
|
from openslides.utils.pdf import firstPage, laterPages
|
||||||
|
|
||||||
@ -164,6 +164,7 @@ class FormView(PermissionMixin, _FormView):
|
|||||||
|
|
||||||
class UpdateView(PermissionMixin, _UpdateView):
|
class UpdateView(PermissionMixin, _UpdateView):
|
||||||
def get_success_url(self):
|
def get_success_url(self):
|
||||||
|
messages.success(self.request, self.get_success_message())
|
||||||
if 'apply' in self.request.POST:
|
if 'apply' in self.request.POST:
|
||||||
return ''
|
return ''
|
||||||
return reverse(super(UpdateView, self).get_success_url())
|
return reverse(super(UpdateView, self).get_success_url())
|
||||||
@ -177,9 +178,13 @@ class UpdateView(PermissionMixin, _UpdateView):
|
|||||||
messages.error(self.request, _('Please check the form for errors.'))
|
messages.error(self.request, _('Please check the form for errors.'))
|
||||||
return super(UpdateView, self).form_invalid(form)
|
return super(UpdateView, self).form_invalid(form)
|
||||||
|
|
||||||
|
def get_success_message(self):
|
||||||
|
return _('%s was successfully modified.') % html_strong(self.object)
|
||||||
|
|
||||||
|
|
||||||
class CreateView(PermissionMixin, _CreateView):
|
class CreateView(PermissionMixin, _CreateView):
|
||||||
def get_success_url(self):
|
def get_success_url(self):
|
||||||
|
messages.success(self.request, self.get_success_message())
|
||||||
if 'apply' in self.request.POST:
|
if 'apply' in self.request.POST:
|
||||||
return reverse(self.get_apply_url(), args=[self.object.id])
|
return reverse(self.get_apply_url(), args=[self.object.id])
|
||||||
return reverse(super(CreateView, self).get_success_url())
|
return reverse(super(CreateView, self).get_success_url())
|
||||||
@ -197,13 +202,16 @@ class CreateView(PermissionMixin, _CreateView):
|
|||||||
messages.error(self.request, _('Please check the form for errors.'))
|
messages.error(self.request, _('Please check the form for errors.'))
|
||||||
return super(CreateView, self).form_invalid(form)
|
return super(CreateView, self).form_invalid(form)
|
||||||
|
|
||||||
|
def get_success_message(self):
|
||||||
|
return _('%s was successfully created.') % html_strong(self.object)
|
||||||
|
|
||||||
|
|
||||||
class DeleteView(RedirectView, SingleObjectMixin):
|
class DeleteView(RedirectView, SingleObjectMixin):
|
||||||
def get_confirm_question(self):
|
def get_confirm_question(self):
|
||||||
return _('Do you really want to delete <b>%s</b>?') % self.object
|
return _('Do you really want to delete %s?') % html_strong(self.object)
|
||||||
|
|
||||||
def get_success_message(self):
|
def get_success_message(self):
|
||||||
return _('Item <b>%s</b> was successfully deleted.') % self.object
|
return _('%s was successfully deleted.') % html_strong(self.object)
|
||||||
|
|
||||||
def pre_redirect(self, request, *args, **kwargs):
|
def pre_redirect(self, request, *args, **kwargs):
|
||||||
self.confirm_form(request, self.object)
|
self.confirm_form(request, self.object)
|
||||||
|
Loading…
Reference in New Issue
Block a user