Added support for CamelCase to RESTModelMixin. See #2480.
This commit is contained in:
parent
0da7765dc0
commit
89192236fc
37
openslides/core/migrations/0004_auto_20170215_1624.py
Normal file
37
openslides/core/migrations/0004_auto_20170215_1624.py
Normal file
@ -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
|
||||||
|
),
|
||||||
|
]
|
@ -34,7 +34,7 @@ class ProjectorMessageElement(ProjectorElement):
|
|||||||
"""
|
"""
|
||||||
Short message on the projector. Rendered as overlay.
|
Short message on the projector. Rendered as overlay.
|
||||||
"""
|
"""
|
||||||
name = 'core/projectormessage'
|
name = 'core/projector-message'
|
||||||
|
|
||||||
def check_data(self):
|
def check_data(self):
|
||||||
if not ProjectorMessage.objects.filter(pk=self.config_entry.get('id')).exists():
|
if not ProjectorMessage.objects.filter(pk=self.config_entry.get('id')).exists():
|
||||||
|
@ -505,7 +505,7 @@ angular.module('OpenSlidesApp.core', [
|
|||||||
'DS',
|
'DS',
|
||||||
function(DS) {
|
function(DS) {
|
||||||
return DS.defineResource({
|
return DS.defineResource({
|
||||||
name: 'core/chatmessage',
|
name: 'core/chat-message',
|
||||||
relations: {
|
relations: {
|
||||||
belongsTo: {
|
belongsTo: {
|
||||||
'users/user': {
|
'users/user': {
|
||||||
@ -689,7 +689,7 @@ angular.module('OpenSlidesApp.core', [
|
|||||||
onConflict: 'replace',
|
onConflict: 'replace',
|
||||||
relations: {
|
relations: {
|
||||||
hasMany: {
|
hasMany: {
|
||||||
'core/projectiondefault': {
|
'core/projection-default': {
|
||||||
localField: 'projectiondefaults',
|
localField: 'projectiondefaults',
|
||||||
foreignKey: 'projector_id',
|
foreignKey: 'projector_id',
|
||||||
}
|
}
|
||||||
@ -713,7 +713,7 @@ angular.module('OpenSlidesApp.core', [
|
|||||||
value.name != 'agenda/item-list' &&
|
value.name != 'agenda/item-list' &&
|
||||||
value.name != 'core/clock' &&
|
value.name != 'core/clock' &&
|
||||||
value.name != 'core/countdown' &&
|
value.name != 'core/countdown' &&
|
||||||
value.name != 'core/message' &&
|
value.name != 'core/projector-message' &&
|
||||||
value.name != 'agenda/current-list-of-speakers' ) {
|
value.name != 'agenda/current-list-of-speakers' ) {
|
||||||
return_dict = {
|
return_dict = {
|
||||||
'state': value.name.replace('/', '.')+'.detail.update',
|
'state': value.name.replace('/', '.')+'.detail.update',
|
||||||
@ -741,7 +741,7 @@ angular.module('OpenSlidesApp.core', [
|
|||||||
'DS',
|
'DS',
|
||||||
function(DS) {
|
function(DS) {
|
||||||
return DS.defineResource({
|
return DS.defineResource({
|
||||||
name: 'core/projectiondefault',
|
name: 'core/projection-default',
|
||||||
relations: {
|
relations: {
|
||||||
belongsTo: {
|
belongsTo: {
|
||||||
'core/projector': {
|
'core/projector': {
|
||||||
@ -762,7 +762,7 @@ angular.module('OpenSlidesApp.core', [
|
|||||||
'$http',
|
'$http',
|
||||||
'Projector',
|
'Projector',
|
||||||
function(DS, jsDataModel, gettext, $http, Projector) {
|
function(DS, jsDataModel, gettext, $http, Projector) {
|
||||||
var name = 'core/projectormessage';
|
var name = 'core/projector-message';
|
||||||
return DS.defineResource({
|
return DS.defineResource({
|
||||||
name: name,
|
name: name,
|
||||||
useClass: jsDataModel,
|
useClass: jsDataModel,
|
||||||
@ -778,7 +778,7 @@ angular.module('OpenSlidesApp.core', [
|
|||||||
var isProjectedIds = this.isProjected();
|
var isProjectedIds = this.isProjected();
|
||||||
var self = this;
|
var self = this;
|
||||||
var predicate = function (element) {
|
var predicate = function (element) {
|
||||||
return element.name == name && element.id == self.id;
|
return element.name === name && element.id === self.id;
|
||||||
};
|
};
|
||||||
_.forEach(isProjectedIds, function (id) {
|
_.forEach(isProjectedIds, function (id) {
|
||||||
var uuid = _.findKey(Projector.get(id).elements, predicate);
|
var uuid = _.findKey(Projector.get(id).elements, predicate);
|
||||||
|
@ -57,7 +57,7 @@ angular.module('OpenSlidesApp.core.projector', ['OpenSlidesApp.core'])
|
|||||||
template: 'static/templates/core/slide_countdown.html',
|
template: 'static/templates/core/slide_countdown.html',
|
||||||
});
|
});
|
||||||
|
|
||||||
slidesProvider.registerSlide('core/projectormessage', {
|
slidesProvider.registerSlide('core/projector-message', {
|
||||||
template: 'static/templates/core/slide_message.html',
|
template: 'static/templates/core/slide_message.html',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1344,7 +1344,7 @@ angular.module('OpenSlidesApp.core.site', [
|
|||||||
ProjectorMessage.create(message).then(function(message){
|
ProjectorMessage.create(message).then(function(message){
|
||||||
$scope.projectors.forEach(function (projector) {
|
$scope.projectors.forEach(function (projector) {
|
||||||
$http.post('/rest/core/projector/' + projector.id + '/activate_elements/', [{
|
$http.post('/rest/core/projector/' + projector.id + '/activate_elements/', [{
|
||||||
name: 'core/projectormessage',
|
name: 'core/projector-message',
|
||||||
stable: true,
|
stable: true,
|
||||||
id: message.id,
|
id: message.id,
|
||||||
identify: true,
|
identify: true,
|
||||||
@ -1358,7 +1358,7 @@ angular.module('OpenSlidesApp.core.site', [
|
|||||||
$scope.removeIdentifierMessages = function () {
|
$scope.removeIdentifierMessages = function () {
|
||||||
Projector.getAll().forEach(function (projector) {
|
Projector.getAll().forEach(function (projector) {
|
||||||
_.forEach(projector.elements, function (element, uuid) {
|
_.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]);
|
$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('#messageSendButton').addClass('disabled');
|
||||||
angular.element('#messageInput').attr('disabled', '');
|
angular.element('#messageInput').attr('disabled', '');
|
||||||
$http.post(
|
$http.post(
|
||||||
'/rest/core/chatmessage/',
|
'/rest/core/chat-message/',
|
||||||
{message: $scope.newMessage}
|
{message: $scope.newMessage}
|
||||||
)
|
)
|
||||||
.success(function () {
|
.success(function () {
|
||||||
@ -1498,7 +1498,7 @@ angular.module('OpenSlidesApp.core.site', [
|
|||||||
});
|
});
|
||||||
|
|
||||||
$scope.clearChatHistory = function () {
|
$scope.clearChatHistory = function () {
|
||||||
$http.post('/rest/core/chatmessage/clear/');
|
$http.post('/rest/core/chat-message/clear/');
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
@ -756,12 +756,6 @@ class MotionChangeRecommendation(RESTModelMixin, models.Model):
|
|||||||
"""Return a string, representing this object."""
|
"""Return a string, representing this object."""
|
||||||
return "Recommendation for Version %s, line %s - %s" % (self.motion_version_id, self.line_from, self.line_to)
|
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):
|
class Category(RESTModelMixin, models.Model):
|
||||||
"""
|
"""
|
||||||
@ -840,11 +834,6 @@ class MotionBlock(RESTModelMixin, models.Model):
|
|||||||
def get_agenda_list_view_title(self):
|
def get_agenda_list_view_title(self):
|
||||||
return self.title
|
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):
|
class MotionLog(RESTModelMixin, models.Model):
|
||||||
"""Save a logmessage for a motion."""
|
"""Save a logmessage for a motion."""
|
||||||
|
@ -722,7 +722,7 @@ angular.module('OpenSlidesApp.motions', [
|
|||||||
'gettextCatalog',
|
'gettextCatalog',
|
||||||
function (DS, Config, jsDataModel, diffService, lineNumberingService, gettextCatalog) {
|
function (DS, Config, jsDataModel, diffService, lineNumberingService, gettextCatalog) {
|
||||||
return DS.defineResource({
|
return DS.defineResource({
|
||||||
name: 'motions/motionchangerecommendation',
|
name: 'motions/motion-change-recommendation',
|
||||||
useClass: jsDataModel,
|
useClass: jsDataModel,
|
||||||
methods: {
|
methods: {
|
||||||
saveStatus: function() {
|
saveStatus: function() {
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
|
from .utils import convert_camel_case_to_pseudo_snake_case
|
||||||
|
|
||||||
|
|
||||||
class MinMaxIntegerField(models.IntegerField):
|
class MinMaxIntegerField(models.IntegerField):
|
||||||
"""
|
"""
|
||||||
@ -46,7 +48,9 @@ class RESTModelMixin:
|
|||||||
None if this is not a so called root rest instance.
|
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.
|
# 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):
|
def get_rest_pk(self):
|
||||||
"""
|
"""
|
||||||
|
@ -1,6 +1,24 @@
|
|||||||
|
import re
|
||||||
import roman
|
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):
|
def to_roman(number):
|
||||||
"""
|
"""
|
||||||
Converts an arabic number within range from 1 to 4999 to the
|
Converts an arabic number within range from 1 to 4999 to the
|
||||||
|
Loading…
Reference in New Issue
Block a user