Add API endpoints for the message of the day app.
This commit is contained in:
80
docs/releases/2.1.8.rst
Normal file
80
docs/releases/2.1.8.rst
Normal file
@@ -0,0 +1,80 @@
|
||||
===============================
|
||||
Mayan EDMS v2.1.8 release notes
|
||||
===============================
|
||||
|
||||
Released: February XX, 2017
|
||||
|
||||
What's new
|
||||
==========
|
||||
|
||||
This is a bug-fix release and all users are encouraged to upgrade. The focus
|
||||
of this micro release was REST API improvement.
|
||||
|
||||
Changes
|
||||
-------------
|
||||
|
||||
- Fixes in the trashed document API endpoints.
|
||||
- Improved tags API PUT and PATCH endpoints.
|
||||
- Bulk document adding when creating and editing tags.
|
||||
- The version of django-mptt is preserved in case mayan-cabinets is installed.
|
||||
- Add Django GPG API endpoints for singing keys.
|
||||
- Add API endpoints for the document states app.
|
||||
- Add API endpoints for the messsage of the day (MOTD) app.
|
||||
|
||||
|
||||
Removals
|
||||
--------
|
||||
* None
|
||||
|
||||
Upgrading from a previous version
|
||||
---------------------------------
|
||||
|
||||
Using PIP
|
||||
~~~~~~~~~
|
||||
|
||||
Type in the console::
|
||||
|
||||
$ pip install -U mayan-edms
|
||||
|
||||
the requirements will also be updated automatically.
|
||||
|
||||
Using Git
|
||||
~~~~~~~~~
|
||||
|
||||
If you installed Mayan EDMS by cloning the Git repository issue the commands::
|
||||
|
||||
$ git reset --hard HEAD
|
||||
$ git pull
|
||||
|
||||
otherwise download the compressed archived and uncompress it overriding the
|
||||
existing installation.
|
||||
|
||||
Next upgrade/add the new requirements::
|
||||
|
||||
$ pip install --upgrade -r requirements.txt
|
||||
|
||||
Common steps
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Migrate existing database schema with::
|
||||
|
||||
$ mayan-edms.py performupgrade
|
||||
|
||||
Add new static media::
|
||||
|
||||
$ mayan-edms.py collectstatic --noinput
|
||||
|
||||
The upgrade procedure is now complete.
|
||||
|
||||
|
||||
Backward incompatible changes
|
||||
=============================
|
||||
|
||||
* None
|
||||
|
||||
Bugs fixed or issues closed
|
||||
===========================
|
||||
|
||||
* None
|
||||
|
||||
.. _PyPI: https://pypi.python.org/pypi/mayan-edms/
|
||||
@@ -22,6 +22,7 @@ versions of the documentation contain the release notes for any later releases.
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
2.1.8
|
||||
2.1.7
|
||||
2.1.6
|
||||
2.1.5
|
||||
|
||||
76
mayan/apps/motd/api_views.py
Normal file
76
mayan/apps/motd/api_views.py
Normal file
@@ -0,0 +1,76 @@
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
from rest_framework import generics
|
||||
|
||||
from rest_api.filters import MayanObjectPermissionsFilter
|
||||
from rest_api.permissions import MayanPermission
|
||||
|
||||
from .models import Message
|
||||
from .permissions import (
|
||||
permission_message_create, permission_message_delete,
|
||||
permission_message_edit, permission_message_view
|
||||
)
|
||||
from .serializers import MessageSerializer
|
||||
|
||||
|
||||
class APIMessageListView(generics.ListCreateAPIView):
|
||||
filter_backends = (MayanObjectPermissionsFilter,)
|
||||
mayan_object_permissions = {'GET': (permission_message_view,)}
|
||||
mayan_view_permissions = {'POST': (permission_message_create,)}
|
||||
permission_classes = (MayanPermission,)
|
||||
queryset = Message.objects.all()
|
||||
serializer_class = MessageSerializer
|
||||
|
||||
def get(self, *args, **kwargs):
|
||||
"""
|
||||
Returns a list of all the messages.
|
||||
"""
|
||||
|
||||
return super(APIMessageListView, self).get(*args, **kwargs)
|
||||
|
||||
def post(self, *args, **kwargs):
|
||||
"""
|
||||
Create a new message.
|
||||
"""
|
||||
|
||||
return super(APIMessageListView, self).post(*args, **kwargs)
|
||||
|
||||
|
||||
class APIMessageView(generics.RetrieveUpdateDestroyAPIView):
|
||||
filter_backends = (MayanObjectPermissionsFilter,)
|
||||
mayan_object_permissions = {
|
||||
'DELETE': (permission_message_delete,),
|
||||
'GET': (permission_message_view,),
|
||||
'PATCH': (permission_message_edit,),
|
||||
'PUT': (permission_message_edit,)
|
||||
}
|
||||
queryset = Message.objects.all()
|
||||
serializer_class = MessageSerializer
|
||||
|
||||
def delete(self, *args, **kwargs):
|
||||
"""
|
||||
Delete the selected message.
|
||||
"""
|
||||
|
||||
return super(APIMessageView, self).delete(*args, **kwargs)
|
||||
|
||||
def get(self, *args, **kwargs):
|
||||
"""
|
||||
Return the details of the selected message.
|
||||
"""
|
||||
|
||||
return super(APIMessageView, self).get(*args, **kwargs)
|
||||
|
||||
def patch(self, *args, **kwargs):
|
||||
"""
|
||||
Edit the selected message.
|
||||
"""
|
||||
|
||||
return super(APIMessageView, self).patch(*args, **kwargs)
|
||||
|
||||
def put(self, *args, **kwargs):
|
||||
"""
|
||||
Edit the selected message.
|
||||
"""
|
||||
|
||||
return super(APIMessageView, self).put(*args, **kwargs)
|
||||
@@ -6,6 +6,7 @@ from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from common import MayanAppConfig, menu_object, menu_secondary, menu_setup
|
||||
from navigation import SourceColumn
|
||||
from rest_api.classes import APIEndPoint
|
||||
|
||||
from .links import (
|
||||
link_message_create, link_message_delete, link_message_edit,
|
||||
@@ -23,6 +24,8 @@ class MOTDApp(MayanAppConfig):
|
||||
def ready(self):
|
||||
super(MOTDApp, self).ready()
|
||||
|
||||
APIEndPoint(app=self, version_string='1')
|
||||
|
||||
Message = self.get_model('Message')
|
||||
|
||||
SourceColumn(
|
||||
|
||||
@@ -13,12 +13,37 @@ class Migration(migrations.Migration):
|
||||
migrations.CreateModel(
|
||||
name='MessageOfTheDay',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('label', models.CharField(max_length=32, verbose_name='Label')),
|
||||
('message', models.TextField(verbose_name='Message', blank=True)),
|
||||
('enabled', models.BooleanField(default=True, verbose_name='Enabled')),
|
||||
('start_datetime', models.DateTimeField(verbose_name='Start date time', blank=True)),
|
||||
('end_datetime', models.DateTimeField(verbose_name='End date time', blank=True)),
|
||||
(
|
||||
'id', models.AutoField(
|
||||
verbose_name='ID', serialize=False,
|
||||
auto_created=True, primary_key=True
|
||||
)
|
||||
),
|
||||
(
|
||||
'label', models.CharField(
|
||||
max_length=32, verbose_name='Label'
|
||||
)
|
||||
),
|
||||
(
|
||||
'message', models.TextField(
|
||||
verbose_name='Message', blank=True
|
||||
)
|
||||
),
|
||||
(
|
||||
'enabled', models.BooleanField(
|
||||
default=True, verbose_name='Enabled'
|
||||
)
|
||||
),
|
||||
(
|
||||
'start_datetime', models.DateTimeField(
|
||||
verbose_name='Start date time', blank=True
|
||||
)
|
||||
),
|
||||
(
|
||||
'end_datetime', models.DateTimeField(
|
||||
verbose_name='End date time', blank=True
|
||||
)
|
||||
),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Message of the day',
|
||||
|
||||
@@ -14,21 +14,33 @@ class Migration(migrations.Migration):
|
||||
migrations.AlterField(
|
||||
model_name='message',
|
||||
name='end_datetime',
|
||||
field=models.DateTimeField(help_text='Date and time until when this message is to be displayed.', null=True, verbose_name='End date time', blank=True),
|
||||
field=models.DateTimeField(
|
||||
help_text='Date and time until when this message is to be displayed.',
|
||||
null=True, verbose_name='End date time', blank=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='message',
|
||||
name='label',
|
||||
field=models.CharField(help_text='Short description of this message.', max_length=32, verbose_name='Label'),
|
||||
field=models.CharField(
|
||||
help_text='Short description of this message.', max_length=32,
|
||||
verbose_name='Label'
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='message',
|
||||
name='message',
|
||||
field=models.TextField(help_text='The actual message to be displayed.', verbose_name='Message'),
|
||||
field=models.TextField(
|
||||
help_text='The actual message to be displayed.',
|
||||
verbose_name='Message'
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='message',
|
||||
name='start_datetime',
|
||||
field=models.DateTimeField(help_text='Date and time after which this message will be displayed.', null=True, verbose_name='Start date time', blank=True),
|
||||
field=models.DateTimeField(
|
||||
help_text='Date and time after which this message will be displayed.',
|
||||
null=True, verbose_name='Start date time', blank=True
|
||||
),
|
||||
),
|
||||
]
|
||||
|
||||
17
mayan/apps/motd/serializers.py
Normal file
17
mayan/apps/motd/serializers.py
Normal file
@@ -0,0 +1,17 @@
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
from rest_framework import serializers
|
||||
|
||||
from .models import Message
|
||||
|
||||
|
||||
class MessageSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
extra_kwargs = {
|
||||
'url': {'view_name': 'rest_api:message-detail'},
|
||||
}
|
||||
fields = (
|
||||
'end_datetime', 'enabled', 'label', 'message', 'start_datetime',
|
||||
'id', 'url'
|
||||
)
|
||||
model = Message
|
||||
6
mayan/apps/motd/tests/literals.py
Normal file
6
mayan/apps/motd/tests/literals.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
TEST_LABEL = 'test label'
|
||||
TEST_LABEL_EDITED = 'test label edited'
|
||||
TEST_MESSAGE = 'test message'
|
||||
TEST_MESSAGE_EDITED = 'test message edited'
|
||||
103
mayan/apps/motd/tests/test_api.py
Normal file
103
mayan/apps/motd/tests/test_api.py
Normal file
@@ -0,0 +1,103 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.test import override_settings
|
||||
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from user_management.tests.literals import (
|
||||
TEST_ADMIN_EMAIL, TEST_ADMIN_PASSWORD, TEST_ADMIN_USERNAME
|
||||
)
|
||||
|
||||
from ..models import Message
|
||||
|
||||
from .literals import (
|
||||
TEST_LABEL, TEST_LABEL_EDITED, TEST_MESSAGE, TEST_MESSAGE_EDITED
|
||||
)
|
||||
|
||||
|
||||
@override_settings(OCR_AUTO_OCR=False)
|
||||
class MOTDAPITestCase(APITestCase):
|
||||
def setUp(self):
|
||||
self.admin_user = get_user_model().objects.create_superuser(
|
||||
username=TEST_ADMIN_USERNAME, email=TEST_ADMIN_EMAIL,
|
||||
password=TEST_ADMIN_PASSWORD
|
||||
)
|
||||
|
||||
self.client.login(
|
||||
username=TEST_ADMIN_USERNAME, password=TEST_ADMIN_PASSWORD
|
||||
)
|
||||
|
||||
def _create_message(self):
|
||||
return Message.objects.create(
|
||||
label=TEST_LABEL, message=TEST_MESSAGE
|
||||
)
|
||||
|
||||
def test_message_create_view(self):
|
||||
response = self.client.post(
|
||||
reverse('rest_api:message-list'), {
|
||||
'label': TEST_LABEL, 'message': TEST_MESSAGE
|
||||
}
|
||||
)
|
||||
|
||||
message = Message.objects.first()
|
||||
self.assertEqual(response.data['id'], message.pk)
|
||||
self.assertEqual(response.data['label'], TEST_LABEL)
|
||||
self.assertEqual(response.data['message'], TEST_MESSAGE)
|
||||
|
||||
self.assertEqual(Message.objects.count(), 1)
|
||||
self.assertEqual(message.label, TEST_LABEL)
|
||||
self.assertEqual(message.message, TEST_MESSAGE)
|
||||
|
||||
def test_message_delete_view(self):
|
||||
message = self._create_message()
|
||||
|
||||
self.client.delete(
|
||||
reverse('rest_api:message-detail', args=(message.pk,))
|
||||
)
|
||||
|
||||
self.assertEqual(Message.objects.count(), 0)
|
||||
|
||||
def test_message_detail_view(self):
|
||||
message = self._create_message()
|
||||
|
||||
response = self.client.get(
|
||||
reverse('rest_api:message-detail', args=(message.pk,))
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
response.data['label'], TEST_LABEL
|
||||
)
|
||||
|
||||
def test_message_path_view(self):
|
||||
message = self._create_message()
|
||||
|
||||
self.client.patch(
|
||||
reverse('rest_api:message-detail', args=(message.pk,)),
|
||||
{
|
||||
'label': TEST_LABEL_EDITED,
|
||||
'message': TEST_MESSAGE_EDITED
|
||||
}
|
||||
)
|
||||
|
||||
message.refresh_from_db()
|
||||
|
||||
self.assertEqual(message.label, TEST_LABEL_EDITED)
|
||||
self.assertEqual(message.message, TEST_MESSAGE_EDITED)
|
||||
|
||||
def test_message_put_view(self):
|
||||
message = self._create_message()
|
||||
|
||||
self.client.put(
|
||||
reverse('rest_api:message-detail', args=(message.pk,)),
|
||||
{
|
||||
'label': TEST_LABEL_EDITED,
|
||||
'message': TEST_MESSAGE_EDITED
|
||||
}
|
||||
)
|
||||
|
||||
message.refresh_from_db()
|
||||
|
||||
self.assertEqual(message.label, TEST_LABEL_EDITED)
|
||||
self.assertEqual(message.message, TEST_MESSAGE_EDITED)
|
||||
@@ -7,8 +7,7 @@ from django.utils import timezone
|
||||
|
||||
from ..models import Message
|
||||
|
||||
TEST_LABEL = 'test label'
|
||||
TEST_MESSAGE = 'test message'
|
||||
from .literals import TEST_LABEL, TEST_MESSAGE
|
||||
|
||||
|
||||
class MOTDTestCase(TestCase):
|
||||
|
||||
@@ -2,6 +2,7 @@ from __future__ import unicode_literals
|
||||
|
||||
from django.conf.urls import patterns, url
|
||||
|
||||
from .api_views import APIMessageListView, APIMessageView
|
||||
from .views import (
|
||||
MessageCreateView, MessageDeleteView, MessageEditView, MessageListView
|
||||
)
|
||||
@@ -10,9 +11,19 @@ urlpatterns = patterns(
|
||||
'',
|
||||
url(r'^list/$', MessageListView.as_view(), name='message_list'),
|
||||
url(r'^create/$', MessageCreateView.as_view(), name='message_create'),
|
||||
url(r'^(?P<pk>\d+)/edit/$', MessageEditView.as_view(), name='message_edit'),
|
||||
url(
|
||||
r'^(?P<pk>\d+)/edit/$', MessageEditView.as_view(), name='message_edit'
|
||||
),
|
||||
url(
|
||||
r'^(?P<pk>\d+)/delete/$', MessageDeleteView.as_view(),
|
||||
name='message_delete'
|
||||
),
|
||||
)
|
||||
|
||||
api_urls = [
|
||||
url(r'^messages/$', APIMessageListView.as_view(), name='message-list'),
|
||||
url(
|
||||
r'^messages/(?P<pk>[0-9]+)/$', APIMessageView.as_view(),
|
||||
name='message-detail'
|
||||
),
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user