Merge branch 'stable/1.5.x'
Conflicts: openslides/projector/projector.py openslides/templates/base.html
This commit is contained in:
commit
cde6232477
@ -27,6 +27,14 @@ Version 1.5.1 (unreleased)
|
||||
==========================
|
||||
[https://github.com/OpenSlides/OpenSlides/issues?milestone=15]
|
||||
|
||||
Participant:
|
||||
- Added permission to see participants also to the manager group.
|
||||
Files:
|
||||
- Fixed error when a file was removed from filesystem.
|
||||
Other:
|
||||
- Fixed http status code when requesting a non-existing static page using
|
||||
Tordado web server.
|
||||
|
||||
|
||||
Version 1.5 (2013-11-25)
|
||||
========================
|
||||
|
@ -98,7 +98,7 @@ def agenda_list_of_speakers(sender, **kwargs):
|
||||
list-of-speakers slide.
|
||||
"""
|
||||
slide = get_active_object()
|
||||
if isinstance(slide, Item):
|
||||
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
|
||||
|
@ -4,6 +4,7 @@ import mimetypes
|
||||
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.db import models
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.utils.translation import ugettext_lazy, ugettext_noop
|
||||
|
||||
from openslides.projector.models import SlideMixin
|
||||
@ -80,15 +81,20 @@ class Mediafile(SlideMixin, models.Model):
|
||||
|
||||
def get_filesize(self):
|
||||
"""
|
||||
Transforms Bytes to Kilobytes or Megabytes. Returns the size as string.
|
||||
Transforms bytes to kilobytes or megabytes. Returns the size as string.
|
||||
"""
|
||||
# TODO: Read http://stackoverflow.com/a/1094933 and think about it.
|
||||
try:
|
||||
size = self.mediafile.size
|
||||
except OSError:
|
||||
size_string = _('unknown')
|
||||
else:
|
||||
if size < 1024:
|
||||
return '< 1 kB'
|
||||
if size >= 1024 * 1024:
|
||||
size_string = '< 1 kB'
|
||||
elif size >= 1024 * 1024:
|
||||
mB = size / 1024 / 1024
|
||||
return '%d MB' % mB
|
||||
size_string = '%d MB' % mB
|
||||
else:
|
||||
kB = size / 1024
|
||||
return '%d kB' % kB
|
||||
size_string = '%d kB' % kB
|
||||
return size_string
|
||||
|
@ -27,7 +27,7 @@
|
||||
{% for mediafile in mediafile_list %}
|
||||
<tr class="{% if mediafile.is_active_slide %}activeline{% endif %}">
|
||||
<td><a href="{{ mediafile.mediafile.url }}">{{ mediafile }}</a></td>
|
||||
<td>{{ mediafile.filetype }}</td>
|
||||
<td>{% trans mediafile.filetype %}</td>
|
||||
<td>{{ mediafile.get_filesize }}</td>
|
||||
<td>{{ mediafile.timestamp }}</td>
|
||||
<td><a href="{{ mediafile.uploader|absolute_url }}">{{ mediafile.uploader }}</a></td>
|
||||
|
@ -118,6 +118,7 @@ def create_builtin_groups_and_admin(sender, **kwargs):
|
||||
|
||||
group_staff = Group.objects.create(name=ugettext_noop('Staff'), pk=4)
|
||||
group_staff.permissions.add(perm_7, perm_9, perm_10, perm_10a, perm_11, perm_12, perm_13, perm_14, perm_15, perm_15a, perm_16)
|
||||
group_staff.permissions.add(perm_6) # TODO: Remove this redundancy after cleanup of the permission system
|
||||
|
||||
# Admin user
|
||||
create_or_reset_admin_user()
|
||||
|
5
openslides/projector/exceptions.py
Normal file
5
openslides/projector/exceptions.py
Normal file
@ -0,0 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
class ProjectorExceptionWarning(RuntimeWarning):
|
||||
pass
|
@ -1,9 +1,12 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from django.conf import settings
|
||||
import warnings
|
||||
|
||||
|
||||
from openslides.config.api import config
|
||||
|
||||
from .exceptions import ProjectorExceptionWarning
|
||||
|
||||
|
||||
class Overlay(object):
|
||||
"""
|
||||
@ -18,6 +21,9 @@ class Overlay(object):
|
||||
self.javascript_callback = get_javascript
|
||||
self.allways_active = allways_active
|
||||
|
||||
def __repr__(self):
|
||||
return self.name
|
||||
|
||||
def get_widget_html(self):
|
||||
"""
|
||||
Returns the html code for the overlay widget.
|
||||
@ -36,10 +42,9 @@ class Overlay(object):
|
||||
try:
|
||||
value = self.get_html_wrapper(self.projector_html_callback())
|
||||
except Exception as exception:
|
||||
if settings.DEBUG:
|
||||
raise exception
|
||||
else:
|
||||
# Catch all errors, so an overlay can not kill the projector
|
||||
warnings.warn('%s in overlay "%s": %s'
|
||||
% (type(exception).__name__, self, exception),
|
||||
ProjectorExceptionWarning)
|
||||
value = ''
|
||||
return value
|
||||
|
||||
|
@ -2,5 +2,4 @@
|
||||
|
||||
<h1>
|
||||
{{ 'welcome_title'|get_config }}
|
||||
<hr>
|
||||
</h1>
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
<h1>
|
||||
{{ slide.title }}
|
||||
<hr>
|
||||
</h1>
|
||||
|
||||
{% if slide.text %}
|
||||
|
@ -72,7 +72,7 @@ $(function () {
|
||||
|
||||
function new_message(text, type) {
|
||||
var message = $('#dummy-notification').clone(true);
|
||||
$(message).removeAttr('id').addClass(type).children('em').html(text);
|
||||
$(message).removeAttr('id').addClass(type).html(text);
|
||||
$('#notifications').append(message);
|
||||
message.slideDown('fast');
|
||||
}
|
||||
|
@ -43,10 +43,10 @@ class DjangoStaticFileHandler(StaticFileHandler):
|
||||
# a shared root prefix
|
||||
# - we do not handle self.default_filename (we do not use it and it
|
||||
# does not make much sense here anyway)
|
||||
if not os.path.exists(absolute_path):
|
||||
if absolute_path is None or not os.path.exists(absolute_path):
|
||||
raise HTTPError(404)
|
||||
if not os.path.isfile(absolute_path):
|
||||
raise HTTPError(403, "%s is not a file", self.path)
|
||||
raise HTTPError(403, 'The requested resource is not a file.')
|
||||
return absolute_path
|
||||
|
||||
|
||||
|
@ -5,6 +5,7 @@ from django.test.client import Client
|
||||
from mock import patch, MagicMock
|
||||
|
||||
from openslides.agenda.models import Item, Speaker
|
||||
from openslides.agenda.signals import agenda_list_of_speakers
|
||||
from openslides.config.api import config
|
||||
from openslides.participant.models import Group, User
|
||||
from openslides.projector.api import set_active_slide
|
||||
@ -300,3 +301,16 @@ class GlobalListOfSpeakersLinks(SpeakerViewTestCase):
|
||||
response = self.admin_client.get('/agenda/list_of_speakers/end_speach/')
|
||||
self.assertRedirects(response, '/dashboard/')
|
||||
self.assertTrue(Speaker.objects.get(item__pk='1').end_time is not None)
|
||||
|
||||
|
||||
class TestOverlay(TestCase):
|
||||
def test_overlay_with_no_model_slide(self):
|
||||
"""
|
||||
When a slide is active, that is not a model (for example the agenda)
|
||||
an Attribute Error was raised.
|
||||
"""
|
||||
config['projector_active_slide'] = {'callback': None}
|
||||
|
||||
value = agenda_list_of_speakers(sender='test').get_projector_html()
|
||||
|
||||
self.assertEqual(value, '')
|
||||
|
@ -255,4 +255,5 @@ class MediafileTest(TestCase):
|
||||
bigfile.seek(1048575)
|
||||
bigfile.write('0')
|
||||
self.assertEqual(object_4.get_filesize(), '1 MB')
|
||||
object_4.mediafile.delete()
|
||||
os.remove(mediafile_4_path)
|
||||
self.assertEqual(object_4.get_filesize(), 'unknown')
|
||||
|
@ -2,9 +2,12 @@
|
||||
|
||||
import re
|
||||
|
||||
from django.contrib.auth.models import Permission
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.test.client import Client
|
||||
|
||||
from openslides.config.api import config
|
||||
from openslides.participant.api import get_registered_group
|
||||
from openslides.participant.models import get_protected_perm, Group, User
|
||||
from openslides.utils.test import TestCase
|
||||
|
||||
@ -93,7 +96,9 @@ class GroupViews(TestCase):
|
||||
class LockoutProtection(TestCase):
|
||||
"""
|
||||
Tests that a manager user can not lockout himself by doing
|
||||
something that removes his last permission to manage participants.
|
||||
something that removes his last permission to manage participants. Tests
|
||||
also that he can see the participant app (although there is no absolute
|
||||
protection).
|
||||
"""
|
||||
def setUp(self):
|
||||
self.user = User.objects.get(pk=1)
|
||||
@ -159,6 +164,17 @@ class LockoutProtection(TestCase):
|
||||
field=None,
|
||||
errors='You can not remove the permission to manage participants from the last group you are in.')
|
||||
|
||||
def test_remove_permission_can_see_participant_from_registered(self):
|
||||
self.assertTrue(self.user.has_perm('participant.can_see_participant'))
|
||||
# Remove perm from registered group
|
||||
can_see_perm = Permission.objects.get(
|
||||
content_type=ContentType.objects.get(app_label='participant', model='user'),
|
||||
codename='can_see_participant')
|
||||
get_registered_group().permissions.remove(can_see_perm)
|
||||
# Reload user
|
||||
self.user = User.objects.get(pk=1)
|
||||
self.assertTrue(self.user.has_perm('participant.can_see_participant'))
|
||||
|
||||
|
||||
class TestUserSettings(TestCase):
|
||||
def setUp(self):
|
||||
|
@ -1,6 +1,8 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from mock import MagicMock, patch
|
||||
import warnings
|
||||
|
||||
from mock import MagicMock
|
||||
|
||||
from openslides.projector.projector import Overlay
|
||||
from openslides.utils.test import TestCase
|
||||
@ -9,18 +11,11 @@ from openslides.utils.test import TestCase
|
||||
class OverlayTest(TestCase):
|
||||
def test_error_in_html(self):
|
||||
"""
|
||||
Tests that the methof get_projector_html does not raise any errors.
|
||||
Tests that the method get_projector_html does not raise any errors.
|
||||
"""
|
||||
get_projector_html = MagicMock(side_effect=Exception('no good error'))
|
||||
overlay = Overlay('test_overlay', lambda: 'widget_html', get_projector_html)
|
||||
|
||||
# Test in productive mode
|
||||
with patch('openslides.projector.projector.settings.DEBUG', False):
|
||||
self.assertEqual(overlay.get_projector_html(), '')
|
||||
|
||||
# Test in debug mode
|
||||
with patch('openslides.projector.projector.settings.DEBUG', True):
|
||||
self.assertRaisesMessage(
|
||||
Exception,
|
||||
'no good error',
|
||||
overlay.get_projector_html)
|
||||
with warnings.catch_warnings(record=True) as warning:
|
||||
overlay.get_projector_html()
|
||||
self.assertEqual(warning[0].message.message, 'Exception in overlay "test_overlay": no good error')
|
||||
|
Loading…
Reference in New Issue
Block a user