Small changes for multiple projector feature.

This commit is contained in:
Norman Jäckel 2016-09-29 15:32:58 +02:00
parent e6b9b21d41
commit 8427ffd816
19 changed files with 112 additions and 133 deletions

View File

@ -20,7 +20,7 @@ Core:
- Added support for big assemblies with lots of users. - Added support for big assemblies with lots of users.
- Added HTML support for messages on the projector. - Added HTML support for messages on the projector.
- Moved custom slides to own app "topics". Renamed it to "Topic". - Moved custom slides to own app "topics". Renamed it to "Topic".
- Added support for multiple projectors - Added support for multiple projectors.
Motions: Motions:
- Added origin field. - Added origin field.

View File

@ -251,7 +251,7 @@ angular.module('OpenSlidesApp.agenda.site', ['OpenSlidesApp.agenda'])
var isAgendaProjectedId = $scope.isAgendaProjected($scope.mainListTree); var isAgendaProjectedId = $scope.isAgendaProjected($scope.mainListTree);
if (isAgendaProjectedId > 0) { if (isAgendaProjectedId > 0) {
// Deactivate // Deactivate
$http.post('/rest/core/projector/' + isAgendaProjectedId + '/prune_elements/', []); $http.post('/rest/core/projector/' + isAgendaProjectedId + '/clear_elements/');
} }
if (isAgendaProjectedId != projectorId) { if (isAgendaProjectedId != projectorId) {
$http.post('/rest/core/projector/' + projectorId + '/prune_elements/', $http.post('/rest/core/projector/' + projectorId + '/prune_elements/',
@ -332,7 +332,7 @@ angular.module('OpenSlidesApp.agenda.site', ['OpenSlidesApp.agenda'])
if (projectiondefaultItem) { if (projectiondefaultItem) {
$scope.defaultProjectorItemId = projectiondefaultItem.projector_id; $scope.defaultProjectorItemId = projectiondefaultItem.projector_id;
} }
var projectiondefaultListOfSpeakers = ProjectionDefault.filter({name: 'list_of_speakers'})[0]; var projectiondefaultListOfSpeakers = ProjectionDefault.filter({name: 'agenda_list_of_speakers'})[0];
if (projectiondefaultListOfSpeakers) { if (projectiondefaultListOfSpeakers) {
$scope.defaultProjectorListOfSpeakersId = projectiondefaultListOfSpeakers.projector_id; $scope.defaultProjectorListOfSpeakersId = projectiondefaultListOfSpeakers.projector_id;
} }
@ -515,16 +515,11 @@ angular.module('OpenSlidesApp.agenda.site', ['OpenSlidesApp.agenda'])
}, function() { }, function() {
$scope.projectors = Projector.getAll(); $scope.projectors = Projector.getAll();
$scope.updateCurrentListOfSpeakers(); $scope.updateCurrentListOfSpeakers();
}); var projectiondefault = ProjectionDefault.filter({name: 'agenda_current_list_of_speakers'})[0];
$scope.$watch(function () {
return Projector.lastModified();
}, function () {
var projectiondefault = ProjectionDefault.filter({name: 'current_list_of_speakers'})[0];
if (projectiondefault) { if (projectiondefault) {
$scope.defaultProjectorId = projectiondefault.projector_id; $scope.defaultProjectorId = projectiondefault.projector_id;
} }
}); });
$scope.updateCurrentListOfSpeakers = function () { $scope.updateCurrentListOfSpeakers = function () {
var itemPromise = CurrentListOfSpeakersItem.getItem($scope.currentListOfSpeakersReference); var itemPromise = CurrentListOfSpeakersItem.getItem($scope.currentListOfSpeakersReference);
if (itemPromise) { if (itemPromise) {
@ -539,7 +534,7 @@ angular.module('OpenSlidesApp.agenda.site', ['OpenSlidesApp.agenda'])
var isCurrentLoSProjectedId = $scope.isCurrentLoSProjected($scope.mainListTree); var isCurrentLoSProjectedId = $scope.isCurrentLoSProjected($scope.mainListTree);
if (isCurrentLoSProjectedId > 0) { if (isCurrentLoSProjectedId > 0) {
// Deactivate // Deactivate
$http.post('/rest/core/projector/' + isCurrentLoSProjectedId + '/prune_elements/', []); $http.post('/rest/core/projector/' + isCurrentLoSProjectedId + '/clear_elements/');
} }
if (isCurrentLoSProjectedId != projectorId) { if (isCurrentLoSProjectedId != projectorId) {
$http.post('/rest/core/projector/' + projectorId + '/prune_elements/', $http.post('/rest/core/projector/' + projectorId + '/prune_elements/',

View File

@ -179,18 +179,19 @@ class Projector(RESTModelMixin, models.Model):
class ProjectionDefault(RESTModelMixin, models.Model): class ProjectionDefault(RESTModelMixin, models.Model):
""" """
Model for the ProjectionDefaults like Motion, Agenda, List of speakers,... Model for the projection defaults like motions, agenda, list of
The name is the technical name like 'topics', 'motions'. For apps the name should speakers and thelike. The name is the technical name like 'topics' or
be the app name to get keep the ProjectionDefault for apps generic. But it is 'motions'. For apps the name should be the app name to get keep the
possible to give some special name like 'list_of_speakers'. ProjectionDefault for apps generic. But it is possible to give some
The display_name is the shown name on the front end for the user. special name like 'list_of_speakers'. The display_name is the shown
name on the front end for the user.
""" """
name = models.CharField(max_length=256) name = models.CharField(max_length=256)
display_name = models.CharField(max_length=256) display_name = models.CharField(max_length=256)
projector = models.ForeignKey( projector = models.ForeignKey(
'Projector', Projector,
on_delete=models.CASCADE, on_delete=models.CASCADE,
related_name='projectiondefaults') related_name='projectiondefaults')

View File

@ -40,8 +40,8 @@ class ProjectorSerializer(ModelSerializer):
class Meta: class Meta:
model = Projector model = Projector
fields = ('id', 'config', 'elements', 'scale', 'scroll', 'name', 'blank', 'width', 'height', 'projectiondefaults') fields = ('id', 'config', 'elements', 'scale', 'scroll', 'name', 'blank', 'width', 'height', 'projectiondefaults', )
read_only_fields = ('scale', 'scroll', 'blank', 'width', 'height', 'projectiondefaults') read_only_fields = ('scale', 'scroll', 'blank', 'width', 'height', )
class TagSerializer(ModelSerializer): class TagSerializer(ModelSerializer):

View File

@ -27,18 +27,20 @@ def delete_django_app_permissions(sender, **kwargs):
def create_builtin_projection_defaults(**kwargs): def create_builtin_projection_defaults(**kwargs):
""" """
Creates the builtin defaults: Creates the builtin defaults:
- agenda_all_items, agenda_item - agenda_all_items, agenda_list_of_speakers, agenda_current_list_of_speakers
- topics
- assignments - assignments
- mediafiles - mediafiles
- motion - motion
- users - users
- list_of_speakers
- current_list_of_speakers
"""
# Check whether ProjectionDefaults exists These strings have to be used in the controllers where you want to
define a projector button. Use the string to get the id of the
responsible projector and pass this id to the projector button directive.
"""
# Check whether ProjectionDefault objects exist.
if ProjectionDefault.objects.all().exists(): if ProjectionDefault.objects.all().exists():
# Do completely nothing if the defaults are already in the database. # Do completely nothing if some defaults are already in the database.
return return
default_projector = Projector.objects.get(pk=1) default_projector = Projector.objects.get(pk=1)
@ -52,11 +54,11 @@ def create_builtin_projection_defaults(**kwargs):
display_name='Topics', display_name='Topics',
projector=default_projector) projector=default_projector)
ProjectionDefault.objects.create( ProjectionDefault.objects.create(
name='list_of_speakers', name='agenda_list_of_speakers',
display_name='List of speakers', display_name='List of speakers',
projector=default_projector) projector=default_projector)
ProjectionDefault.objects.create( ProjectionDefault.objects.create(
name='current_list_of_speakers', name='agenda_current_list_of_speakers',
display_name='Current list of speakers', display_name='Current list of speakers',
projector=default_projector) projector=default_projector)
ProjectionDefault.objects.create( ProjectionDefault.objects.create(

View File

@ -192,10 +192,12 @@ angular.module('OpenSlidesApp.core', [
autoupdate.onMessage(function(json) { autoupdate.onMessage(function(json) {
// TODO: when MODEL.find() is called after this // TODO: when MODEL.find() is called after this
// a new request is fired. This could be a bug in DS // a new request is fired. This could be a bug in DS
// TODO: If you don't have the permission to see a projector, the var dataList = [];
// variable json is a string with an error message. Therefor try {
// the next line fails. dataList = JSON.parse(json);
var dataList = JSON.parse(json); } catch(err) {
console.error(json);
}
_.forEach(dataList, function(data) { _.forEach(dataList, function(data) {
console.log("Received object: " + data.collection + ", " + data.id); console.log("Received object: " + data.collection + ", " + data.id);
var instance = DS.get(data.collection, data.id); var instance = DS.get(data.collection, data.id);
@ -313,15 +315,17 @@ angular.module('OpenSlidesApp.core', [
} }
]) ])
// This places a Projectorbutton in the document. Example: /*
// <projector-button model="motion" default-projector.id="defPrId" additional-id="2" * This places a projector button in the document.
// content="{{ 'project' | translate }}"></projector-button> *
// * Example: <projector-button model="motion" default-projector.id="defPrId"
// This button references to model (in this case 'motion'). Also a defaultProjectionId has to * additional-id="2" content="{{ 'project' | translate }}"></projector-button>
// be given. In the Exable its a scope variable. The next two parameters are additional: * This button references to model (in this example 'motion'). Also a defaultProjectionId
// - additional-id: Then the model.project and model.isProjected will be called whith this * has to be given. In the example it's a scope variable. The next two parameters are additional:
// argument (ex.: model.project(2)) * - additional-id: Then the model.project and model.isProjected will be called with
// - content: A not trusted text placed behind the projector symbol. * this argument (e. g.: model.project(2))
* - content: A text placed behind the projector symbol.
*/
.directive('projectorButton', [ .directive('projectorButton', [
'Projector', 'Projector',
function (Projector) { function (Projector) {
@ -370,7 +374,7 @@ angular.module('OpenSlidesApp.core', [
// if this object is already projected on projectorId, delete this element from this projector // if this object is already projected on projectorId, delete this element from this projector
var isProjectedId = this.isProjected(); var isProjectedId = this.isProjected();
if (isProjectedId > 0) { if (isProjectedId > 0) {
$http.post('/rest/core/projector/' + isProjectedId + '/prune_elements/'); $http.post('/rest/core/projector/' + isProjectedId + '/clear_elements/');
} }
// if it was the same projector before, just delete it but not show again // if it was the same projector before, just delete it but not show again
if (isProjectedId != projectorId) { if (isProjectedId != projectorId) {
@ -483,7 +487,7 @@ angular.module('OpenSlidesApp.core', [
}, },
getStateForCurrentSlide: function () { getStateForCurrentSlide: function () {
var return_dict; var return_dict;
$.each(this.elements, function(key, value) { angular.forEach(this.elements, function(key, value) {
if (value.name == 'agenda/list-of-speakers') { if (value.name == 'agenda/list-of-speakers') {
return_dict = { return_dict = {
'state': 'agenda.item.detail', 'state': 'agenda.item.detail',
@ -592,11 +596,13 @@ angular.module('OpenSlidesApp.core', [
} }
]) ])
// This filter filters all items in array. If the filterArray is empty, the array is passed. /*
// The filterArray contains numbers of the multiselect: [1, 3, 4]. * This filter filters all items in an array. If the filterArray is empty, the
// Then, all items in array are passed, if the item_id (get with id_function) matches one of the * array is passed. The filterArray contains numbers of the multiselect, e. g. [1, 3, 4].
// ids in filterArray. id_function could also return a list of ids. Example: * Then, all items in the array are passed, if the item_id (get with id_function) matches
// Item 1 has two tags with ids [1, 4]. filterArray = [3, 4] --> match * one of the ids in filterArray. id_function could also return a list of ids. Example:
* Item 1 has two tags with ids [1, 4]. filterArray == [3, 4] --> match
*/
.filter('SelectMultipleFilter', [ .filter('SelectMultipleFilter', [
function () { function () {
return function (array, filterArray, idFunction) { return function (array, filterArray, idFunction) {

View File

@ -60,10 +60,11 @@ angular.module('OpenSlidesApp.core.projector', ['OpenSlidesApp.core'])
.controller('ProjectorContainerCtrl', [ .controller('ProjectorContainerCtrl', [
'$scope', '$scope',
'$location', '$location',
'gettext',
'loadGlobalData', 'loadGlobalData',
'Projector', 'Projector',
'ProjectorID', 'ProjectorID',
function($scope, $location, loadGlobalData, Projector, ProjectorID) { function($scope, $location, gettext, loadGlobalData, Projector, ProjectorID) {
loadGlobalData(); loadGlobalData();
$scope.projector_id = ProjectorID(); $scope.projector_id = ProjectorID();
@ -73,18 +74,16 @@ angular.module('OpenSlidesApp.core.projector', ['OpenSlidesApp.core'])
$scope.$watch(function () { $scope.$watch(function () {
return Projector.lastModified($scope.projector_id); return Projector.lastModified($scope.projector_id);
}, function () { }, function () {
Projector.find($scope.projector_id).then(function (projector) { var projector = Projector.get($scope.projector_id)
if (projector) {
$scope.error = '';
$scope.projectorWidth = projector.width; $scope.projectorWidth = projector.width;
$scope.projectorHeight = projector.height; $scope.projectorHeight = projector.height;
$scope.recalculateIframe(); $scope.recalculateIframe();
}, function (error) { } else {
if (error.status == 404) { $scope.error = gettext('Can not open the projector.');
$scope.error = 'Projector not found.';
} else if (error.status == 403) {
$scope.error = 'You have to login to see the projector.';
} }
}); });
});
// recalculate the actual Iframesize and scale // recalculate the actual Iframesize and scale
$scope.recalculateIframe = function () { $scope.recalculateIframe = function () {
@ -164,7 +163,6 @@ angular.module('OpenSlidesApp.core.projector', ['OpenSlidesApp.core'])
$scope.$watch(function () { $scope.$watch(function () {
return Config.lastModified('projector_broadcast'); return Config.lastModified('projector_broadcast');
}, function () { }, function () {
Config.findAll().then(function () {
var bc = Config.get('projector_broadcast').value; var bc = Config.get('projector_broadcast').value;
if ($scope.broadcast != bc) { if ($scope.broadcast != bc) {
$scope.broadcast = bc; $scope.broadcast = bc;
@ -176,7 +174,6 @@ angular.module('OpenSlidesApp.core.projector', ['OpenSlidesApp.core'])
$scope.blank = $scope.projector.blank; $scope.blank = $scope.projector.blank;
} }
} }
if ($scope.broadcast > 0) { if ($scope.broadcast > 0) {
// get elements and blank from broadcast projector // get elements and blank from broadcast projector
$scope.broadcastDeregister = $scope.$watch(function () { $scope.broadcastDeregister = $scope.$watch(function () {
@ -192,7 +189,6 @@ angular.module('OpenSlidesApp.core.projector', ['OpenSlidesApp.core'])
}); });
} }
}); });
});
$scope.$on('$destroy', function() { $scope.$on('$destroy', function() {
if ($scope.broadcastDeregister) { if ($scope.broadcastDeregister) {

View File

@ -1616,7 +1616,7 @@ angular.module('OpenSlidesApp.core.site', [
}; };
$scope.removeIdentifierMessages = function () { $scope.removeIdentifierMessages = function () {
Projector.getAll().forEach(function (projector) { Projector.getAll().forEach(function (projector) {
$.each(projector.elements, function (uuid, value) { angular.forEach(projector.elements, function (uuid, value) {
if (value.name == 'core/message' && value.type == 'identify') { if (value.name == 'core/message' && value.type == 'identify') {
$http.post('/rest/core/projector/' + projector.id + '/deactivate_elements/', [uuid]); $http.post('/rest/core/projector/' + projector.id + '/deactivate_elements/', [uuid]);
} }

View File

@ -56,7 +56,7 @@
<li ng-repeat="projectiondefault in projectiondefaults | orderBy:'id'" <li ng-repeat="projectiondefault in projectiondefaults | orderBy:'id'"
ng-click="setProjectionDefault(projector, projectiondefault)"> ng-click="setProjectionDefault(projector, projectiondefault)">
<i class="fa fa-check" ng-if="projectiondefault.projector_id === projector.id"></i> <i class="fa fa-check" ng-if="projectiondefault.projector_id === projector.id"></i>
<translate>{{ projectiondefault.display_name }}</translate> {{ projectiondefault.display_name | translate }}
</li> </li>
</ul> </ul>
</div> </div>

View File

@ -20,7 +20,7 @@
ng-class="{ 'projected': (model.isProjected(additionalId) == projector.id) }"> ng-class="{ 'projected': (model.isProjected(additionalId) == projector.id) }">
<i class="fa fa-video-camera" ng-show="model.isProjected(additionalId) == projector.id"></i> <i class="fa fa-video-camera" ng-show="model.isProjected(additionalId) == projector.id"></i>
{{ projector.name }} {{ projector.name }}
<span ng-if="defaultProjectorId == projector.id">(<translate>Standard</translate>)</span> <span ng-if="defaultProjectorId == projector.id">(<translate>Default</translate>)</span>
</a> </a>
</li> </li>
</ul> </ul>

View File

@ -18,7 +18,6 @@ from django.utils.timezone import now
from openslides import __version__ as version from openslides import __version__ as version
from openslides.utils import views as utils_views from openslides.utils import views as utils_views
from openslides.utils.autoupdate import inform_changed_data
from openslides.utils.plugins import ( from openslides.utils.plugins import (
get_plugin_description, get_plugin_description,
get_plugin_verbose_name, get_plugin_verbose_name,
@ -190,23 +189,25 @@ class ProjectorViewSet(ModelViewSet):
result = self.get_access_permissions().check_permissions(self.request.user) result = self.get_access_permissions().check_permissions(self.request.user)
elif self.action == 'metadata': elif self.action == 'metadata':
result = self.request.user.has_perm('core.can_see_projector') result = self.request.user.has_perm('core.can_see_projector')
elif self.action in ('activate_elements', 'prune_elements', 'update_elements', elif self.action in (
'deactivate_elements', 'clear_elements', 'control_view', 'create', 'update', 'partial_update', 'destroy',
'set_resolution', 'set_scroll', 'control_blank', 'destroy', 'activate_elements', 'prune_elements', 'update_elements', 'deactivate_elements', 'clear_elements',
'create', 'update', 'broadcast', 'set_projectiondefault'): 'control_view', 'set_resolution', 'set_scroll', 'control_blank', 'broadcast',
'set_projectiondefault',
):
result = (self.request.user.has_perm('core.can_see_projector') and result = (self.request.user.has_perm('core.can_see_projector') and
self.request.user.has_perm('core.can_manage_projector')) self.request.user.has_perm('core.can_manage_projector'))
else: else:
result = False result = False
return result return result
# Assign all projectionDefaults from this projector to the default projector (pk=1) # Assign all ProjectionDefault objects from this projector to the default projector (pk=1).
def destroy(self, *args, **kwargs): def destroy(self, *args, **kwargs):
projector_instance = self.get_object() projector_instance = self.get_object()
for a in ProjectionDefault.objects.all(): for projection_default in ProjectionDefault.objects.all():
if a.projector.id == projector_instance.id: if projection_default.projector.id == projector_instance.id:
a.projector = Projector.objects.get(pk=1) projection_default.projector_id = 1
a.save() projection_default.save()
return super(ProjectorViewSet, self).destroy(*args, **kwargs) return super(ProjectorViewSet, self).destroy(*args, **kwargs)
@detail_route(methods=['post']) @detail_route(methods=['post'])
@ -486,8 +487,6 @@ class ProjectorViewSet(ModelViewSet):
""" """
if config['projector_broadcast'] == 0: if config['projector_broadcast'] == 0:
config['projector_broadcast'] = pk config['projector_broadcast'] = pk
projector_instance = self.get_object()
inform_changed_data(projector_instance)
message = "Setting projector {id} as broadcast projector was successful.".format( message = "Setting projector {id} as broadcast projector was successful.".format(
id=pk) id=pk)
else: else:

View File

@ -158,7 +158,7 @@ angular.module('OpenSlidesApp.mediafiles.site', ['ngFileUpload', 'OpenSlidesApp.
$scope.showMediafile = function (projectorId, mediafile) { $scope.showMediafile = function (projectorId, mediafile) {
var isProjectedId = mediafile.isProjected(); var isProjectedId = mediafile.isProjected();
if (isProjectedId > 0) { if (isProjectedId > 0) {
$http.post('/rest/core/projector/' + isProjectedId + '/prune_elements/', []); $http.post('/rest/core/projector/' + isProjectedId + '/clear_elements/');
} }
if (isProjectedId != projectorId) { if (isProjectedId != projectorId) {
var postUrl = '/rest/core/projector/' + projectorId + '/prune_elements/'; var postUrl = '/rest/core/projector/' + projectorId + '/prune_elements/';
@ -177,9 +177,6 @@ angular.module('OpenSlidesApp.mediafiles.site', ['ngFileUpload', 'OpenSlidesApp.
} }
}; };
// To avoid some kind of 60,000000000001% in template
$scope.round = function (val) {return Math.round(val);};
var sendMediafileCommand = function (mediafile, data) { var sendMediafileCommand = function (mediafile, data) {
var updateData = _.extend({}, mediafile); var updateData = _.extend({}, mediafile);
_.extend(updateData, data); _.extend(updateData, data);

View File

@ -196,7 +196,7 @@
<td ng-show="!isDeleteMode" <td ng-show="!isDeleteMode"
os-perms="core.can_manage_projector"> os-perms="core.can_manage_projector">
<div class="btn-group" style="min-width:54px;" uib-dropdown <div class="btn-group" style="min-width:54px;" uib-dropdown
ng-if="mediafile.mediafile.is_presentable" ng-if="mediafile.is_presentable"
uib-tooltip="{{ 'Projektor' | translate }} {{ mediafile.isProjected() }}" uib-tooltip="{{ 'Projektor' | translate }} {{ mediafile.isProjected() }}"
tooltip-enable="mediafile.isProjected() > 0"> tooltip-enable="mediafile.isProjected() > 0">
<button type="button" class="btn btn-default btn-sm" <button type="button" class="btn btn-default btn-sm"

View File

@ -79,9 +79,7 @@ angular.module('OpenSlidesApp.motions.projector', ['OpenSlidesApp.motions'])
} }
}; };
Motion.find(id).then(function (motion) { Motion.bindOne(id, $scope, 'motion');
$scope.motion = motion;
});
User.bindAll({}, $scope, 'users'); User.bindAll({}, $scope, 'users');
} }

View File

@ -1217,7 +1217,6 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions', 'OpenSlid
$scope.$watch(function () { $scope.$watch(function () {
return Projector.lastModified(); return Projector.lastModified();
}, function () { }, function () {
console.log(ProjectionDefault.getAll());
$scope.defaultProjectorId = ProjectionDefault.filter({name: 'motions'})[0].projector_id; $scope.defaultProjectorId = ProjectionDefault.filter({name: 'motions'})[0].projector_id;
}); });
$scope.version = motion.active_version; $scope.version = motion.active_version;

View File

@ -64,7 +64,7 @@ def ws_add_projector(message, projector_id):
""" """
user = message.user user = message.user
# user is the django anonymous user. We have our own. # user is the django anonymous user. We have our own.
if user.is_anonymous: if user.is_anonymous and config['general_systen_enable_anonymous']:
user = AnonymousUser() user = AnonymousUser()
if not user.has_perm('core.can_see_projector'): if not user.has_perm('core.can_see_projector'):
@ -140,12 +140,9 @@ def send_data(message):
broadcast_id = config['projector_broadcast'] broadcast_id = config['projector_broadcast']
if broadcast_id > 0: if broadcast_id > 0:
projectors = Projector.objects.all() # also the broadcasted projector should get data projectors = Projector.objects.all() # Also the broadcasted projector should get his data
broadcast_projector = Projector.objects.get(pk=broadcast_id)
send_all = True send_all = True
# The data from the broadcasted projector broadcast_projector_data = get_projector_element_data(Projector.objects.get(pk=broadcast_id))
broadcast_projector_data = get_projector_element_data(broadcast_projector)
else: else:
broadcast_projector_data = None broadcast_projector_data = None

View File

@ -14,7 +14,6 @@ from rest_framework.routers import DefaultRouter
from rest_framework.serializers import ModelSerializer as _ModelSerializer from rest_framework.serializers import ModelSerializer as _ModelSerializer
from rest_framework.serializers import ( # noqa from rest_framework.serializers import ( # noqa
MANY_RELATION_KWARGS, MANY_RELATION_KWARGS,
BooleanField,
CharField, CharField,
DictField, DictField,
Field, Field,

View File

@ -26,22 +26,12 @@ class ProjectorAPI(TestCase):
response = self.client.get(reverse('projector-detail', args=['1'])) response = self.client.get(reverse('projector-detail', args=['1']))
content = json.loads(response.content.decode()) content = json.loads(response.content.decode())
del content['projectiondefaults']
self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(content, { self.assertEqual(content['elements'], {
'id': 1,
'elements': {
'aae4a07b26534cfb9af4232f361dce73': 'aae4a07b26534cfb9af4232f361dce73':
{'id': topic.id, {'id': topic.id,
'uuid': 'aae4a07b26534cfb9af4232f361dce73', 'uuid': 'aae4a07b26534cfb9af4232f361dce73',
'name': 'topics/topic'}}, 'name': 'topics/topic'}})
'scale': 0,
'scroll': 0,
'name': 'Defaultprojector',
'blank': False,
'width': 1024,
'height': 768})
def test_invalid_slide_on_default_projector(self): def test_invalid_slide_on_default_projector(self):
self.client.login(username='admin', password='admin') self.client.login(username='admin', password='admin')