def get_ajax_context(self, *args, **kwargs): config['pdf_fullscreen'] = not config['pdf_fullscreen'] active_slide = get_active_slide() if active_slide['callback'] == 'mediafile': ProjectorSocketHandler.send_updates( {'calls': {'toggle_fullscreen': config['pdf_fullscreen']}}) return {'fullscreen': config['pdf_fullscreen']}
def get_context_data(self, **kwargs): context = super(Overview, self).get_context_data(**kwargs) context.update({ 'items': Item.objects.all(), 'active_sid': get_active_slide(only_sid=True), }) return context
def post(self, request, *args, **kwargs): if not request.user.has_perm('agenda.can_manage_agenda'): messages.error(request, _('You are not authorized to manage the agenda.')) context = self.get_context_data(**kwargs) return self.render_to_response(context) transaction.commit() for item in Item.objects.all(): form = ItemOrderForm(request.POST, prefix="i%d" % item.id) if form.is_valid(): try: parent = Item.objects.get(id=form.cleaned_data['parent']) except Item.DoesNotExist: parent = None item.weight = form.cleaned_data['weight'] item.parent = parent Model.save(item) else: transaction.rollback() messages.error(request, _('Errors when reordering of the agenda')) break else: Item.objects.rebuild() # TODO: assure, that it is a valid tree context = self.get_context_data(**kwargs) transaction.commit() if get_active_slide()['callback'] == 'agenda': update_projector() context = self.get_context_data(**kwargs) transaction.commit() return self.render_to_response(context)
def get_projector_html(): """ Returns an html-code to show on the projector. The overlay is only shown on agenda-items and not on the list-of-speakers slide. """ slide = get_active_object() if slide is None or isinstance(slide, Item): item = slide else: # TODO: If there is more than one item, use the first one in the # mptt tree that is not closed. try: item = Item.objects.filter( content_type=ContentType.objects.get_for_model(slide), object_id=slide.pk)[0] except IndexError: item = None if item and get_active_slide().get('type', None) != 'list_of_speakers': list_of_speakers = item.get_list_of_speakers( old_speakers_count=config['agenda_show_last_speakers'], coming_speakers_count=5) value = render_to_string( 'agenda/overlay_speaker_projector.html', { 'list_of_speakers': list_of_speakers, 'closed': item.speaker_list_closed }) else: value = None return value
def save(self, *args, **kwargs): super(Item, self).save(*args, **kwargs) active_slide = get_active_slide() active_slide_pk = active_slide.get('pk', None) if (active_slide['callback'] == 'agenda' and unicode(self.parent_id) == unicode(active_slide_pk)): update_projector()
def get_projector_html(): """ Returns an html-code to show on the projector. The overlay is only shown on agenda-items and not on the list-of-speakers slide. """ slide = get_active_object() if slide is None or isinstance(slide, Item): item = slide else: # TODO: If there are more the one items, use the first one in the # mptt tree that is not closed try: item = Item.objects.filter( content_type=ContentType.objects.get_for_model(slide), object_id=slide.pk)[0] except IndexError: item = None if item and get_active_slide().get('type', None) != 'list_of_speakers': list_of_speakers = item.get_list_of_speakers( old_speakers_count=config['agenda_show_last_speakers'], coming_speakers_count=5) value = render_to_string('agenda/overlay_speaker_projector.html', { 'list_of_speakers': list_of_speakers, 'closed': item.speaker_list_closed}) else: value = None return value
def post(self, request, *args, **kwargs): if not request.user.has_perm('agenda.can_manage_agenda'): messages.error( request, _('You are not authorized to manage the agenda.')) context = self.get_context_data(**kwargs) return self.render_to_response(context) transaction.commit() for item in Item.objects.all(): form = ItemOrderForm(request.POST, prefix="i%d" % item.id) if form.is_valid(): try: parent = Item.objects.get(id=form.cleaned_data['parent']) except Item.DoesNotExist: parent = None item.weight = form.cleaned_data['weight'] item.parent = parent Model.save(item) else: transaction.rollback() messages.error( request, _('Errors when reordering of the agenda')) break else: Item.objects.rebuild() # TODO: assure, that it is a valid tree context = self.get_context_data(**kwargs) transaction.commit() if get_active_slide()['callback'] == 'agenda': update_projector() context = self.get_context_data(**kwargs) transaction.commit() return self.render_to_response(context)
def active(self): """ Return True, if the the slide is the active slide. """ if self.id is None: return False from openslides.projector.api import get_active_slide return get_active_slide(only_sid=True) == self.sid
def get_context_data(self, **context): pdfs = Mediafile.objects.filter( filetype__in=Mediafile.PRESENTABLE_FILE_TYPES, is_presentable=True) current_page = get_active_slide().get('page_num', 1) return super(PDFPresentationWidget, self).get_context_data(pdfs=pdfs, current_page=current_page, **context)
def is_active_slide(self): """ Return True, if the the slide is the active slide. """ from openslides.projector.api import get_active_slide active_slide = get_active_slide() slide_pk = int_or_none(active_slide.get('pk', None)) return (active_slide['callback'] == self.slide_callback_name and self.pk == slide_pk)
def get_context_data(self, **context): pdfs = Mediafile.objects.filter( filetype__in=Mediafile.PRESENTABLE_FILE_TYPES, is_presentable=True) current_page = get_active_slide().get('page_num', 1) return super(PDFPresentationWidget, self).get_context_data( pdfs=pdfs, current_page=current_page, **context)
def save(self, *args, **kwargs): """ Updates the projector if a topicvoting slide is on it. """ value = super(Category, self).save(*args, **kwargs) callback = get_active_slide()['callback'] if callback == 'topicvoting_category_list' or callback == 'topicvoting_result': update_projector() return value
def get_item(self): """ Returns the current Item, or None, if the current Slide is not an Agenda Item. """ slide = get_slide_from_sid(get_active_slide(only_sid=True), element=True) if not isinstance(slide, Item): return None else: return slide
def get_context_data(self, **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)
def get_ajax_context(self, *args, **kwargs): config['pdf_fullscreen'] = not config['pdf_fullscreen'] active_slide = get_active_slide() if active_slide['callback'] == 'mediafile': ProjectorSocketHandler.send_updates( {'calls': { 'toggle_fullscreen': config['pdf_fullscreen'] }}) return {'fullscreen': config['pdf_fullscreen']}
def get_context_data(self, **kwargs): context = super(Overview, self).get_context_data(**kwargs) if self.request.user.has_perm('agenda.can_see_orga_items'): items = Item.objects.all() else: items = Item.objects.filter(type__exact=Item.AGENDA_ITEM) # Save the items as a list (not a queryset). This is important, # because in other case, django-mtpp reloads the items in the # template. But we add some attributes (in this function), which are # not in the database and would be lost if the items were reloaded. # TODO: Try to remove this line in later versions of django-mptt items = list(items) start = config['agenda_start_event_date_time'] if start is None or len(start) == 0: start = None else: start = datetime.strptime(start, '%d.%m.%Y %H:%M') duration = timedelta() for item in items: if (item.duration is not None and len(item.duration) > 0): duration_list = item.duration.split(':') duration += timedelta(hours=int(duration_list[0]), minutes=int(duration_list[1])) if not start is None: item.tooltip = start + duration if start is None: end = None else: end = start + duration duration = u'%d:%02d' % ( (duration.days * 24 + duration.seconds / 3600.0), (duration.seconds / 60.0 % 60)) context.update({ 'items': items, 'active_sid': get_active_slide(only_sid=True), 'duration': duration, 'start': start, 'end': end, 'summary': config['presentation_argument'] == 'summary', 'show_list': config['presentation_argument'] == 'show_list_of_speakers' }) return context
def get(self, request, *args, **kwargs): target_page = int(request.GET.get('page_num')) self.active_slide = get_active_slide() if target_page: self.active_slide['page_num'] = target_page self.load_other_page(self.active_slide) response = super(PdfGoToPageView, self).get(self, request, *args, **kwargs) else: response = HttpResponse() return response
def get(self, request, *args, **kwargs): self.active_slide = get_active_slide() if self.active_slide['callback'] == 'openslides_video': self.active_slide['video_playing'] = False self.active_slide['video_fullscreen'] = False self.update_video_state(self.active_slide) response = super(VideoPauseView, self).get(self, request, *args, **kwargs) else: response = HttpResponse() return response
def save(self, *args, **kwargs): """ Updates the projector if a topicvoting slide is on it. """ # TODO: Look for all cases and switch off unused update value = super(Topic, self).save(*args, **kwargs) callback = get_active_slide()['callback'] if callback and callback.startswith('topicvoting'): update_projector() return value
def check_and_update_projector(self): """ Checks, if the agenda item, or parts of it, is on the projector. If yes, it updates the projector. """ if self.item.is_active_slide(): if get_active_slide().get('type', None) == 'list_of_speakers': update_projector() else: update_projector_overlay('agenda_speaker')
def get_item(self): """ Returns the current Item, or None, if the current Slide is not an Agenda Item. """ active_slide = get_active_slide() if active_slide['callback'] == 'agenda': try: return Item.objects.get(pk=active_slide.get('pk', None)) except Item.DoesNotExist: return None else: return None
def form_valid(self, form): """ Saves the CreateForm or UpdateForm into a motion object. """ self.object = form.save(commit=False) try: self.object.category = form.cleaned_data['category'] except KeyError: pass try: self.object.identifier = form.cleaned_data['identifier'] except KeyError: pass self.manipulate_object(form) for attr in ['title', 'text', 'reason']: setattr(self.version, attr, form.cleaned_data[attr]) self.object.save(use_version=self.version) # Save the submitter an the supporter so the motion. # TODO: Only delete and save neccessary submitters and supporters if 'submitter' in form.cleaned_data: self.object.submitter.all().delete() MotionSubmitter.objects.bulk_create([ MotionSubmitter(motion=self.object, person=person) for person in form.cleaned_data['submitter'] ]) if 'supporter' in form.cleaned_data: self.object.supporter.all().delete() MotionSupporter.objects.bulk_create([ MotionSupporter(motion=self.object, person=person) for person in form.cleaned_data['supporter'] ]) # Save the attachments self.object.attachments.clear() self.object.attachments.add(*form.cleaned_data['attachments']) # Update the projector if the motion is on it. This can not be done in # the model, because bulk_create does not call the save method. active_slide = get_active_slide() active_slide_pk = active_slide.get('pk', None) if (active_slide['callback'] == 'motion' and str(self.object.pk) == str(active_slide_pk)): update_projector() messages.success(self.request, self.get_success_message()) return HttpResponseRedirect(self.get_success_url())
def testActivate(self): c = self.adminClient response = c.get('/projector/activate/%s/' % self.item1.sid) self.assertEqual(response.status_code, 302) self.assertTrue(self.item1.active) self.assertFalse(self.item2.active) response = c.get('/projector/activate/%s/' % 'agenda') self.assertEqual(response.status_code, 302) self.assertFalse(self.item2.active) self.assertFalse(self.item1.active) self.assertEqual(get_active_slide(only_sid=True), 'agenda')
def get_context_data(self, **kwargs): self.object = self.get_object() list_of_speakers = self.object.get_list_of_speakers() active_slide = get_active_slide() active_type = active_slide.get('type', None) kwargs.update({ 'object': self.object, 'list_of_speakers': list_of_speakers, 'is_on_the_list_of_speakers': Speaker.objects.filter( item=self.object, begin_time=None, person=self.request.user).exists(), 'active_type': active_type, }) return super(AgendaItemView, self).get_context_data(**kwargs)
def get_context_data(self, **context): active_slide = get_active_slide() if active_slide['callback'] == 'agenda': agenda_is_active = active_slide.get('pk', 'agenda') == 'agenda' active_type = active_slide.get('type', 'text') else: agenda_is_active = None active_type = None context.update({ 'agenda_is_active': agenda_is_active, 'items': Item.objects.all(), 'active_type': active_type}) return super(AgendaWidget, self).get_context_data(**context)
def get_context_data(self, **kwargs): self.object = self.get_object() list_of_speakers = self.object.get_list_of_speakers() active_slide = get_active_slide() active_type = active_slide.get('type', None) kwargs.update({ 'object': self.object, 'list_of_speakers': list_of_speakers, 'is_on_the_list_of_speakers': Speaker.objects.filter( item=self.object, begin_time=None, user=self.request.user).exists(), 'active_type': active_type, }) return super(AgendaItemView, self).get_context_data(**kwargs)
def check_and_update_projector(self): """ Checks, if the agenda item, or parts of it, is on the projector. If yes, it updates the projector. """ active_slide = get_active_slide() active_slide_pk = active_slide.get('pk', None) slide_type = active_slide.get('type', None) if (active_slide['callback'] == 'agenda' and unicode(self.item_id) == unicode(active_slide_pk)): if slide_type == 'list_of_speakers': update_projector() elif slide_type is None: update_projector_overlay('agenda_speaker')
def get_context_data(self, **kwargs): context = super(Overview, self).get_context_data(**kwargs) if self.request.user.has_perm('agenda.can_see_orga_items'): items = Item.objects.all() else: items = Item.objects.filter(type__exact=Item.AGENDA_ITEM) # Save the items as a list (not a queryset). This is important, # because in other case, django-mtpp reloads the items in the # template. But we add some attributes (in this function), which are # not in the database and would be lost if the items were reloaded. # TODO: Try to remove this line in later versions of django-mptt items = list(items) start = config['agenda_start_event_date_time'] if start is None or len(start) == 0: start = None else: start = datetime.strptime(start, '%d.%m.%Y %H:%M') duration = timedelta() for item in items: if (item.duration is not None and len(item.duration) > 0): duration_list = item.duration.split(':') duration += timedelta(hours=int(duration_list[0]), minutes=int(duration_list[1])) if not start is None: item.tooltip = start + duration if start is None: end = None else: end = start + duration duration = u'%d:%02d' % ( (duration.days * 24 + duration.seconds / 3600.0), (duration.seconds / 60.0 % 60)) context.update({ 'items': items, 'active_sid': get_active_slide(only_sid=True), 'duration': duration, 'start': start, 'end': end, 'summary': config['presentation_argument'] == 'summary', 'show_list': config['presentation_argument'] == 'show_list_of_speakers'}) return context
def get_context_data(self, **context): active_slide = get_active_slide() if active_slide['callback'] == 'agenda': agenda_is_active = active_slide.get('pk', 'agenda') == 'agenda' active_type = active_slide.get('type', 'text') else: agenda_is_active = None active_type = None context.update({ 'agenda_is_active': agenda_is_active, 'items': Item.objects.all(), 'active_type': active_type }) return super(AgendaWidget, self).get_context_data(**context)
def form_valid(self, form): """ Saves the CreateForm or UpdateForm into a motion object. """ self.object = form.save(commit=False) try: self.object.category = form.cleaned_data['category'] except KeyError: pass try: self.object.identifier = form.cleaned_data['identifier'] except KeyError: pass self.manipulate_object(form) for attr in ['title', 'text', 'reason']: setattr(self.version, attr, form.cleaned_data[attr]) self.object.save(use_version=self.version) # Save the submitter an the supporter so the motion. # TODO: Only delete and save neccessary submitters and supporters if 'submitter' in form.cleaned_data: self.object.submitter.all().delete() MotionSubmitter.objects.bulk_create( [MotionSubmitter(motion=self.object, person=person) for person in form.cleaned_data['submitter']]) if 'supporter' in form.cleaned_data: self.object.supporter.all().delete() MotionSupporter.objects.bulk_create( [MotionSupporter(motion=self.object, person=person) for person in form.cleaned_data['supporter']]) # Save the attachments self.object.attachments.clear() self.object.attachments.add(*form.cleaned_data['attachments']) # Update the projector if the motion is on it. This can not be done in # the model, because bulk_create does not call the save method. active_slide = get_active_slide() active_slide_pk = active_slide.get('pk', None) if (active_slide['callback'] == 'motion' and unicode(self.object.pk) == unicode(active_slide_pk)): update_projector() messages.success(self.request, self.get_success_message()) return HttpResponseRedirect(self.get_success_url())
def data(self): try: return self._data except AttributeError: pass sid = self.kwargs['sid'] if sid is None: try: data = get_active_slide() except AttributeError: #TODO: It has to be an Slide.DoesNotExist data = None ajax = 'on' active_sid = get_active_slide(True) else: data = get_slide_from_sid(sid) ajax = 'off' if data is None: data = { 'title': config['event_name'], 'template': 'projector/default.html', } data['overlays'] = [] data['ajax'] = ajax # Projector Overlays if self.kwargs['sid'] is None: active_defs = ProjectorOverlay.objects.filter(active=True) \ .filter(Q(sid=active_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: data['overlays'].append(response) self._data = data return data
def get(self, request, *args, **kwargs): """ Decrement the page number by 1. If the page number is set and it is greater than 1, it is decremented by 1. Otherwise, it is the first page and nothing happens. """ self.active_slide = get_active_slide() response = None if self.active_slide['callback'] == 'mediafile': if 'page_num' in self.active_slide and self.active_slide['page_num'] > 1: self.active_slide['page_num'] -= 1 self.load_other_page(self.active_slide) response = super(PdfPreviousView, self).get(self, request, *args, **kwargs) if not response: response = HttpResponse() return response
def get(self, request, *args, **kwargs): """ Decrement the page number by 1. If the page number is set and it is greater than 1, it is decremented by 1. Otherwise, it is the first page and nothing happens. """ self.active_slide = get_active_slide() response = None if self.active_slide['callback'] == 'mediafile': if 'page_num' in self.active_slide and self.active_slide[ 'page_num'] > 1: self.active_slide['page_num'] -= 1 self.load_other_page(self.active_slide) response = super(PdfPreviousView, self).get(self, request, *args, **kwargs) if not response: response = HttpResponse() return response
def get(self, request, *args, **kwargs): """ Increment the page number by 1. If the page number is set in the active slide, we are the value is incremented by 1. Otherwise, it is the first page and it is set to 2. """ self.active_slide = get_active_slide() if self.active_slide['callback'] == 'mediafile': if 'page_num' not in self.active_slide: self.active_slide['page_num'] = 2 else: self.active_slide['page_num'] += 1 self.load_other_page(self.active_slide) response = super(PdfNextView, self).get(self, request, *args, **kwargs) else: # no Mediafile is active and the JavaScript should not do anything. response = HttpResponse() return response
def get_projector_html(): """ Returns an html-code to show on the projector. """ slide = get_slide_from_sid(get_active_slide(only_sid=True), element=True) if not isinstance(slide, Item): # Only show list of speakers overlay on agenda items return None if config['presentation_argument'] == 'show_list_of_speakers': # Do not show list of speakers overlay on the list of speakers slide return None clear_projector_cache() list_of_speakers = slide.get_list_of_speakers( old_speakers_count=config['agenda_show_last_speakers'], coming_speakers_count=5) context = { 'list_of_speakers': list_of_speakers, 'closed': slide.speaker_list_closed, } return render_to_string('agenda/overlay_speaker_projector.html', context)
def get_widgets(request): """ Return the widgets of the projector app """ widgets = [] # PDF-Presentation widget pdfs = Mediafile.objects.filter( filetype__in=Mediafile.PRESENTABLE_FILE_TYPES, is_presentable=True ) current_page = get_active_slide().get('page_num', 1) widgets.append(Widget( request, name='presentations', display_name=_('Presentations'), template='mediafile/pdfs_widget.html', context={'pdfs': pdfs, 'current_page': current_page, 'pdf_fullscreen': config['pdf_fullscreen']}, permission_required='projector.can_manage_projector', default_column=1, default_weight=75)) return widgets
def get_projector_html(): """ Returns an html-code to show on the projector. The overlay is only shown on agenda-items and not on the list-of-speakers slide. """ active_slide = get_active_slide() slide_type = active_slide.get('type', None) active_slide_pk = active_slide.get('pk', None) if (active_slide['callback'] == 'agenda' and slide_type != 'list_of_speakers' and active_slide_pk is not None): item = Item.objects.get(pk=active_slide_pk) list_of_speakers = item.get_list_of_speakers( old_speakers_count=config['agenda_show_last_speakers'], coming_speakers_count=5) context = { 'list_of_speakers': list_of_speakers, 'closed': item.speaker_list_closed, } return render_to_string('agenda/overlay_speaker_projector.html', context) else: return None
def active(self): """ Return True if the Slide is active, else: False. """ from api import get_active_slide return get_active_slide(True) == self.key
def get_context_data(self, **context): return super(CustonSlideWidget, self).get_context_data( slides=ProjectorSlide.objects.all().order_by('weight'), welcomepage_is_active=get_active_slide().get('callback', 'default') == 'default', **context)
def get_context_data(self, **kwargs): context = super(Overview, self).get_context_data(**kwargs) if self.request.user.has_perm('agenda.can_see_orga_items'): items = Item.objects.all() else: items = Item.objects.filter(type__exact=Item.AGENDA_ITEM) # Save the items as a list (not a queryset). This is important, # because in other case, django-mtpp reloads the items in the # template. But we add some attributes (in this function), which are # not in the database and would be lost if the items were reloaded. # TODO: Try to remove this line in later versions of django-mptt items = list(items) start = config['agenda_start_event_date_time'] if start is None or len(start) == 0: start = None else: start = datetime.strptime(start, '%d.%m.%Y %H:%M') duration = timedelta() for item in items: if item.duration is not None and len(item.duration) > 0: if ':' in item.duration: duration_list = item.duration.split(':') duration += timedelta(hours=int(duration_list[0]), minutes=int(duration_list[1])) else: hours = int(item.duration) / 60 minutes = int(item.duration) - (60 * hours) duration += timedelta(hours=hours, minutes=minutes) if minutes < 10: minutes = "%s%s" % (0, minutes) item.duration = "%s:%s" % (hours, minutes) if start is not None: item.tooltip = start + duration if start is None: end = None else: end = start + duration duration = u'%d:%02d' % ( (duration.days * 24 + duration.seconds / 3600.0), (duration.seconds / 60.0 % 60)) active_slide = get_active_slide() if active_slide['callback'] == 'agenda': agenda_is_active = active_slide.get('pk', 'agenda') == 'agenda' active_type = active_slide.get('type', 'text') else: agenda_is_active = None active_type = None context.update({ 'items': items, 'agenda_is_active': agenda_is_active, 'duration': duration, 'start': start, 'end': end, 'active_type': active_type }) return context
def test_get_active_slide(self): mock_config = {'projector_active_slide': 'value'} with patch('openslides.projector.api.config', mock_config): value = projector_api.get_active_slide() self.assertEqual(value, 'value')
def get_context_data(self, **kwargs): context = super(Overview, self).get_context_data(**kwargs) if self.request.user.has_perm('agenda.can_see_orga_items'): items = Item.objects.all() else: items = Item.objects.filter(type__exact=Item.AGENDA_ITEM) # Save the items as a list (not a queryset). This is important, # because in other case, django-mtpp reloads the items in the # template. But we add some attributes (in this function), which are # not in the database and would be lost if the items were reloaded. # TODO: Try to remove this line in later versions of django-mptt items = list(items) start = config['agenda_start_event_date_time'] if start is None or len(start) == 0: start = None else: start = datetime.strptime(start, '%d.%m.%Y %H:%M') duration = timedelta() for item in items: if item.duration is not None and len(item.duration) > 0: if ':' in item.duration: duration_list = item.duration.split(':') duration += timedelta(hours=int(duration_list[0]), minutes=int(duration_list[1])) else: hours = int(item.duration) / 60 minutes = int(item.duration) - (60 * hours) duration += timedelta(hours=hours, minutes=minutes) if minutes < 10: minutes = "%s%s" % (0, minutes) item.duration = "%s:%s" % (hours, minutes) if not start is None: item.tooltip = start + duration if start is None: end = None else: end = start + duration duration = u'%d:%02d' % ( (duration.days * 24 + duration.seconds / 3600.0), (duration.seconds / 60.0 % 60)) active_slide = get_active_slide() if active_slide['callback'] == 'agenda': agenda_is_active = active_slide.get('pk', 'agenda') == 'agenda' active_type = active_slide.get('type', 'text') else: agenda_is_active = None active_type = None context.update({ 'items': items, 'agenda_is_active': agenda_is_active, 'duration': duration, 'start': start, 'end': end, 'active_type': active_type}) return context
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)