diff --git a/openslides/core/migrations/0004_auto_20170215_1624.py b/openslides/core/migrations/0004_auto_20170215_1624.py new file mode 100644 index 000000000..36d0bcee3 --- /dev/null +++ b/openslides/core/migrations/0004_auto_20170215_1624.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.5 on 2017-02-15 15:24 +from __future__ import unicode_literals + +from django.db import migrations + + +def rename_projector_message_slides(apps, schema_editor): + """ + Renames projector message slides in projector model. + + Old name 'core/projectormessage', new name 'core/projector-message'. + """ + # We get the model from the versioned app registry; + # if we directly import it, it will be the wrong version. + Projector = apps.get_model('core', 'Projector') + for projector in Projector.objects.all(): + new_config = {} + for key, value in projector.config.items(): + new_config[key] = value + if value['name'] == 'core/projectormessage': + new_config[key]['name'] = 'core/projector-message' + projector.config = new_config + projector.save(skip_autoupdate=True) + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0003_auto_20161217_1158'), + ] + + operations = [ + migrations.RunPython( + rename_projector_message_slides + ), + ] diff --git a/openslides/core/projector.py b/openslides/core/projector.py index a0b46c1e0..747ef222c 100644 --- a/openslides/core/projector.py +++ b/openslides/core/projector.py @@ -34,7 +34,7 @@ class ProjectorMessageElement(ProjectorElement): """ Short message on the projector. Rendered as overlay. """ - name = 'core/projectormessage' + name = 'core/projector-message' def check_data(self): if not ProjectorMessage.objects.filter(pk=self.config_entry.get('id')).exists(): diff --git a/openslides/core/static/js/core/base.js b/openslides/core/static/js/core/base.js index e81e49659..af6498a89 100644 --- a/openslides/core/static/js/core/base.js +++ b/openslides/core/static/js/core/base.js @@ -505,7 +505,7 @@ angular.module('OpenSlidesApp.core', [ 'DS', function(DS) { return DS.defineResource({ - name: 'core/chatmessage', + name: 'core/chat-message', relations: { belongsTo: { 'users/user': { @@ -689,7 +689,7 @@ angular.module('OpenSlidesApp.core', [ onConflict: 'replace', relations: { hasMany: { - 'core/projectiondefault': { + 'core/projection-default': { localField: 'projectiondefaults', foreignKey: 'projector_id', } @@ -713,7 +713,7 @@ angular.module('OpenSlidesApp.core', [ value.name != 'agenda/item-list' && value.name != 'core/clock' && value.name != 'core/countdown' && - value.name != 'core/message' && + value.name != 'core/projector-message' && value.name != 'agenda/current-list-of-speakers' ) { return_dict = { 'state': value.name.replace('/', '.')+'.detail.update', @@ -741,7 +741,7 @@ angular.module('OpenSlidesApp.core', [ 'DS', function(DS) { return DS.defineResource({ - name: 'core/projectiondefault', + name: 'core/projection-default', relations: { belongsTo: { 'core/projector': { @@ -762,7 +762,7 @@ angular.module('OpenSlidesApp.core', [ '$http', 'Projector', function(DS, jsDataModel, gettext, $http, Projector) { - var name = 'core/projectormessage'; + var name = 'core/projector-message'; return DS.defineResource({ name: name, useClass: jsDataModel, @@ -778,7 +778,7 @@ angular.module('OpenSlidesApp.core', [ var isProjectedIds = this.isProjected(); var self = this; var predicate = function (element) { - return element.name == name && element.id == self.id; + return element.name === name && element.id === self.id; }; _.forEach(isProjectedIds, function (id) { var uuid = _.findKey(Projector.get(id).elements, predicate); diff --git a/openslides/core/static/js/core/projector.js b/openslides/core/static/js/core/projector.js index ec83bac23..7da04d285 100644 --- a/openslides/core/static/js/core/projector.js +++ b/openslides/core/static/js/core/projector.js @@ -57,7 +57,7 @@ angular.module('OpenSlidesApp.core.projector', ['OpenSlidesApp.core']) template: 'static/templates/core/slide_countdown.html', }); - slidesProvider.registerSlide('core/projectormessage', { + slidesProvider.registerSlide('core/projector-message', { template: 'static/templates/core/slide_message.html', }); } diff --git a/openslides/core/static/js/core/site.js b/openslides/core/static/js/core/site.js index 783984b32..6bb903410 100644 --- a/openslides/core/static/js/core/site.js +++ b/openslides/core/static/js/core/site.js @@ -1344,7 +1344,7 @@ angular.module('OpenSlidesApp.core.site', [ ProjectorMessage.create(message).then(function(message){ $scope.projectors.forEach(function (projector) { $http.post('/rest/core/projector/' + projector.id + '/activate_elements/', [{ - name: 'core/projectormessage', + name: 'core/projector-message', stable: true, id: message.id, identify: true, @@ -1358,7 +1358,7 @@ angular.module('OpenSlidesApp.core.site', [ $scope.removeIdentifierMessages = function () { Projector.getAll().forEach(function (projector) { _.forEach(projector.elements, function (element, uuid) { - if (element.name == 'core/projectormessage' && element.id == $scope.identifierMessage.id) { + if (element.name === 'core/projector-message' && element.id === $scope.identifierMessage.id) { $http.post('/rest/core/projector/' + projector.id + '/deactivate_elements/', [uuid]); } }); @@ -1469,7 +1469,7 @@ angular.module('OpenSlidesApp.core.site', [ angular.element('#messageSendButton').addClass('disabled'); angular.element('#messageInput').attr('disabled', ''); $http.post( - '/rest/core/chatmessage/', + '/rest/core/chat-message/', {message: $scope.newMessage} ) .success(function () { @@ -1498,7 +1498,7 @@ angular.module('OpenSlidesApp.core.site', [ }); $scope.clearChatHistory = function () { - $http.post('/rest/core/chatmessage/clear/'); + $http.post('/rest/core/chat-message/clear/'); }; } ]) diff --git a/openslides/motions/models.py b/openslides/motions/models.py index a939c962a..bf04d9b6d 100644 --- a/openslides/motions/models.py +++ b/openslides/motions/models.py @@ -756,12 +756,6 @@ class MotionChangeRecommendation(RESTModelMixin, models.Model): """Return a string, representing this object.""" return "Recommendation for Version %s, line %s - %s" % (self.motion_version_id, self.line_from, self.line_to) - def get_root_rest_element(self): - """ - Returns this instance, which is the root REST element. - """ - return self - class Category(RESTModelMixin, models.Model): """ @@ -840,11 +834,6 @@ class MotionBlock(RESTModelMixin, models.Model): def get_agenda_list_view_title(self): return self.title - @classmethod - def get_collection_string(cls): - # TODO: Fix generic method to support camelCase, #2480. - return 'motions/motion-block' - class MotionLog(RESTModelMixin, models.Model): """Save a logmessage for a motion.""" diff --git a/openslides/motions/static/js/motions/base.js b/openslides/motions/static/js/motions/base.js index 8b9d392c0..930be6767 100644 --- a/openslides/motions/static/js/motions/base.js +++ b/openslides/motions/static/js/motions/base.js @@ -722,7 +722,7 @@ angular.module('OpenSlidesApp.motions', [ 'gettextCatalog', function (DS, Config, jsDataModel, diffService, lineNumberingService, gettextCatalog) { return DS.defineResource({ - name: 'motions/motionchangerecommendation', + name: 'motions/motion-change-recommendation', useClass: jsDataModel, methods: { saveStatus: function() { diff --git a/openslides/utils/models.py b/openslides/utils/models.py index eac60b948..d145faa6b 100644 --- a/openslides/utils/models.py +++ b/openslides/utils/models.py @@ -1,5 +1,7 @@ from django.db import models +from .utils import convert_camel_case_to_pseudo_snake_case + class MinMaxIntegerField(models.IntegerField): """ @@ -46,7 +48,9 @@ class RESTModelMixin: None if this is not a so called root rest instance. """ # TODO Check if this is a root rest element class and return None if not. - return '/'.join((cls._meta.app_label.lower(), cls._meta.object_name.lower())) + return '/'.join( + (convert_camel_case_to_pseudo_snake_case(cls._meta.app_label), + convert_camel_case_to_pseudo_snake_case(cls._meta.object_name))) def get_rest_pk(self): """ diff --git a/openslides/utils/utils.py b/openslides/utils/utils.py index b2d01f01e..3770046cb 100644 --- a/openslides/utils/utils.py +++ b/openslides/utils/utils.py @@ -1,6 +1,24 @@ +import re import roman +CAMEL_CASE_TO_PSEUDO_SNAKE_CASE_CONVERSION_REGEX_1 = re.compile('(.)([A-Z][a-z]+)') +CAMEL_CASE_TO_PSEUDO_SNAKE_CASE_CONVERSION_REGEX_2 = re.compile('([a-z0-9])([A-Z])') + + +def convert_camel_case_to_pseudo_snake_case(text): + """ + Converts camel case to pseudo snake case using hyphen instead of + underscore. + + E. g. ThisText is converted to this-text. + + Credits: epost (http://stackoverflow.com/a/1176023) + """ + s1 = CAMEL_CASE_TO_PSEUDO_SNAKE_CASE_CONVERSION_REGEX_1.sub(r'\1-\2', text) + return CAMEL_CASE_TO_PSEUDO_SNAKE_CASE_CONVERSION_REGEX_2.sub(r'\1-\2', s1).lower() + + def to_roman(number): """ Converts an arabic number within range from 1 to 4999 to the