--- a/server/src/metaeducation/settings/__init__.py Mon Jul 04 00:31:19 2016 +0200
+++ b/server/src/metaeducation/settings/__init__.py Tue Jul 05 13:19:38 2016 +0200
@@ -59,7 +59,7 @@
),
'DEFAULT_PARSER_CLASSES': (
'rest_framework.parsers.JSONParser',
- ),
+ ),
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination'
}
@@ -72,7 +72,9 @@
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware','guardian.backends.ObjectPermissionBackend',
- 'metaeducation.middleware.MtdcLoginRequiredWithContextMiddleware'
+ 'metaeducation.middleware.MtdcLoginRequiredWithContextMiddleware',
+ 'metaeducation.tracking.middleware.TrackingMiddleware'
+
)
ROOT_URLCONF = 'metaeducation.urls'
--- a/server/src/metaeducation/static/metaeducation/css/style.css Mon Jul 04 00:31:19 2016 +0200
+++ b/server/src/metaeducation/static/metaeducation/css/style.css Tue Jul 05 13:19:38 2016 +0200
@@ -4,17 +4,17 @@
.errorModal {
font-family: Arial, Helvetica, sans-serif;
- display: none;
- position: fixed;
- z-index: 1000;
- padding-top: 100px;
+ display: none;
+ position: fixed;
+ z-index: 1000;
+ padding-top: 100px;
left: 0;
top: 0;
- width: 100%;
- height: 100%;
- overflow: auto;
- background-color: rgb(0,0,0);
- background-color: rgba(35,0,0,0.4);
+ width: 100%;
+ height: 100%;
+ overflow: auto;
+ background-color: rgb(0,0,0);
+ background-color: rgba(35,0,0,0.4);
}
/* Modal Content */
@@ -34,7 +34,7 @@
/* Add Animation */
@-webkit-keyframes animatetop {
- from {top:-300px; opacity:0}
+ from {top:-300px; opacity:0}
to {top:0; opacity:1}
}
@@ -65,4 +65,23 @@
.errorMsg{
display: none;
+}
+
+.renkanlist-action {
+ padding: 0 0.3em;
+}
+.renkan-del-form {
+ display: inline-block;
+}
+
+.renkan-del-button {
+ color: #337ab7;
+ text-decoration: none;
+ border: none;
+ background: none;
+}
+
+.renkan-del-button:hover, .renkan-del-button:focus {
+ color: #23527c;
+ text-decoration: underline;
}
\ No newline at end of file
--- a/server/src/metaeducation/templates/renkan_list.html Mon Jul 04 00:31:19 2016 +0200
+++ b/server/src/metaeducation/templates/renkan_list.html Tue Jul 05 13:19:38 2016 +0200
@@ -29,9 +29,13 @@
<td>{{renkan.title}}</td>
<td>{{renkan.creation_date}}</td>
<td>
- <a href="{% url 'front_view_renkan' renkan_guid=renkan.renkan_guid %}" >View</a>
- <a href="{% url 'front_edit_renkan' renkan_guid=renkan.renkan_guid %}" >Edit</a>
- <a href="{% url 'front_delete_renkan' renkan_guid=renkan.renkan_guid %}" >Delete</a>
+ <a href="{% url 'front_view_renkan' renkan_guid=renkan.renkan_guid %}" class="renkanlist-action">View</a>
+ <a href="{% url 'front_edit_renkan' renkan_guid=renkan.renkan_guid %}" class="renkanlist-action">Edit</a>
+ <form action="{% url 'front_delete_renkan' %}" method="post" class="renkan-del-form" >
+ {% csrf_token %}
+ <input type="hidden" name="renkan_guid" value="{{renkan.renkan_guid}}">
+ <button type="submit" class="renkan-del-button renkan-list-action">Delete</button>
+ </form>
</td>
</tr>
{% endfor %}
@@ -43,4 +47,4 @@
<br><br>
</div>
</footer>
-{% endblock main_content %}
\ No newline at end of file
+{% endblock main_content %}
--- a/server/src/metaeducation/tracking/__init__.py Mon Jul 04 00:31:19 2016 +0200
+++ b/server/src/metaeducation/tracking/__init__.py Tue Jul 05 13:19:38 2016 +0200
@@ -1,4 +1,8 @@
from .tasks import send_tracking_data
-from .messages import send_close_renkan, send_open_edit_renkan, send_open_read_renkan
+from .messages import send_close_renkan, send_open_edit_renkan, send_open_read_renkan, \
+ send_delete_renkan, send_create_renkan, send_update_renkan
-__all__ = ['send_tracking_data', 'send_close_renkan', 'send_open_read_renkan', 'send_open_edit_renkan']
+__all__ = [
+ 'send_tracking_data', 'send_close_renkan', 'send_open_read_renkan', 'send_open_edit_renkan',
+ 'send_delete_renkan', 'send_update_renkan', 'send_create_renkan'
+]
--- a/server/src/metaeducation/tracking/messages.py Mon Jul 04 00:31:19 2016 +0200
+++ b/server/src/metaeducation/tracking/messages.py Tue Jul 05 13:19:38 2016 +0200
@@ -2,6 +2,7 @@
import json
import logging
import pytz
+import functools
from .tasks import send_tracking_data
@@ -118,7 +119,7 @@
msg = get_base_message('open_edit', renkan.renkan_guid, current_user, registration)
msg['object'] = {
- **(msg['object']),
+ **(msg.get('object', {})),
**{
"definition": {
"name": {
@@ -133,3 +134,58 @@
}
send_tracking_data(msg)
+
+def _send_operation_renkan(action, renkan, current_user, content=None):
+ if not content:
+ content = json.loads(renkan.content)
+ title = renkan.title
+ renkan_guid = renkan.renkan_guid
+ else:
+ content = json.loads(content)
+ title = content.get('title', '')
+ renkan_guid = content.get('id', content.get('_id', ''))
+ msg = get_base_message(action, renkan_guid, current_user)
+ msg['object'] = {
+ **(msg.get('object',{})),
+ **{
+ "definition": {
+ "name": {
+ 'fr-FR': title
+ },
+ "type": "http://www.w3.org/ns/activitystreams#Renkan",
+ "extensions": {
+ 'http://www.w3.org/ns/activitystreams#Data': content,
+ }
+ }
+ }
+ }
+ send_tracking_data(msg)
+
+
+send_delete_renkan = functools.partial(_send_operation_renkan, 'delete')
+send_update_renkan = functools.partial(_send_operation_renkan, 'update')
+
+def send_create_renkan(renkan, current_user):
+ msg = get_base_message('create', renkan.renkan_guid, current_user)
+ msg['object'] = {
+ **(msg.get('object', {})),
+ **{
+ "definition": {
+ "name": {
+ 'fr-FR': renkan.title
+ },
+ "type": "http://www.w3.org/ns/activitystreams#Renkan",
+ "extensions": {
+ 'http://www.w3.org/ns/activitystreams#Data': json.loads(renkan.content),
+ }
+ }
+ }
+ }
+ if renkan.source_revision:
+ msg['context']['extensions'] = {
+ **msg.get('context', {}).get('extensions', {}),
+ **{
+ 'http://liris.renkantracking.org/fromCreate': {'renkan': renkan.source_revision.parent_renkan.renkan_guid, 'revision': renkan.source_revision.revision_guid}
+ }
+ }
+ send_tracking_data(msg)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/metaeducation/tracking/middleware.py Tue Jul 05 13:19:38 2016 +0200
@@ -0,0 +1,59 @@
+import logging
+import uuid
+
+from django.db.models.signals import pre_delete, post_save
+from django.utils.functional import curry
+
+from renkanmanager.models import Renkan, Revision
+
+from . import send_delete_renkan, send_create_renkan, send_update_renkan
+
+logger = logging.getLogger(__name__)
+
+class TrackingMiddleware(object):
+ def process_request(self, request):
+ if not request.method in ('GET', 'HEAD', 'OPTIONS', 'TRACE'):
+ if hasattr(request, 'user') and request.user.is_authenticated():
+ user = request.user.external_id
+ else:
+ user = None
+
+ request.renkan_request_id = uuid.uuid4()
+
+ pre_delete.connect(curry(self.renkan_delete, user), sender=Renkan, dispatch_uid = (self.__class__, request.renkan_request_id,), weak=False)
+ post_save.connect(curry(self.revision_save, user), sender=Revision, dispatch_uid = (self.__class__, request.renkan_request_id,), weak=False)
+
+ def process_response(self, request, response):
+ if hasattr(request, 'renkan_request_id'):
+ pre_delete.disconnect(dispatch_uid = (self.__class__, request.renkan_request_id,))
+ post_save.disconnect(dispatch_uid = (self.__class__, request.renkan_request_id,))
+ return response
+
+ def process_exception(self, request, exception):
+ if hasattr(request, 'renkan_request_id'):
+ pre_delete.disconnect(dispatch_uid = (self.__class__, request.renkan_request_id,))
+ post_save.disconnect(dispatch_uid = (self.__class__, request.renkan_request_id,))
+ return None
+
+ def process_view(self, request, view_func, view_args, view_kwargs):
+ if view_func.__name__ == 'RenkanDetail' and view_func.__module__ == 'renkanmanager.api.views' and request.method == 'PUT' and 'renkan_guid' in view_kwargs:
+ if hasattr(request, 'user') and request.user.is_authenticated():
+ user = request.user.external_id
+ else:
+ user = None
+ send_update_renkan(None, user, request.body.decode('utf-8'))
+ return None
+
+
+ def renkan_delete(self, user, sender, **kwargs):
+ renkan = kwargs.get('instance', None)
+ if not renkan:
+ return
+ send_delete_renkan(renkan, user)
+
+ def revision_save(self, user, sender, **kwargs):
+ revision = kwargs.get('instance', None)
+ if not revision:
+ return
+ if kwargs.get('created', False) and revision.parent_renkan.revision_count <= 1:
+ send_create_renkan(revision.parent_renkan, user)
--- a/server/src/metaeducation/urls.py Mon Jul 04 00:31:19 2016 +0200
+++ b/server/src/metaeducation/urls.py Tue Jul 05 13:19:38 2016 +0200
@@ -34,7 +34,7 @@
url(r'^front/view/(?P<renkan_guid>[\w-]+)/$', ViewRenkanView.as_view(), name='front_view_renkan'),
url(r'^tracking/$', UITrackingView.as_view(), name='tracking_view'),
url(r'^tracking/close/$', UITrackingViewClose.as_view(), name='tracking_view_close'),
- url(r'^front/delete/(?P<renkan_guid>[\w-]+)/$', staff_member_required(DeleteRenkanView.as_view()), name='front_delete_renkan')
+ url(r'^front/delete/$', staff_member_required(DeleteRenkanView.as_view()), name='front_delete_renkan')
]
urlpatterns += staticfiles_urlpatterns()
--- a/server/src/metaeducation/views/renkan.py Mon Jul 04 00:31:19 2016 +0200
+++ b/server/src/metaeducation/views/renkan.py Tue Jul 05 13:19:38 2016 +0200
@@ -1,5 +1,6 @@
import logging, json, uuid
+from django import forms
from django.conf import settings
from django.core.urlresolvers import reverse
from django.http import HttpResponse, HttpResponseRedirect
@@ -72,10 +73,17 @@
send_open_edit_renkan(renkan, str(request.user.external_id), str(context['registration']))
return self.render_to_response(context)
+class DeleteForm(forms.Form):
+ renkan_guid = forms.UUIDField()
class DeleteRenkanView(View):
- def get(self, request, renkan_guid):
- request.method = "DELETE"
- delete_response = RenkanDetail.as_view()(request, renkan_guid)
- return HttpResponseRedirect(request.META.get('HTTP_REFERER', settings.BASE_URL))
+ def post(self, request):
+ form = DeleteForm(request.POST)
+ if form.is_valid():
+ renkan_guid = form.cleaned_data['renkan_guid']
+ logger.debug("DELETE FORM VALID %r", form.cleaned_data)
+ request.method = "DELETE"
+ delete_response = RenkanDetail.as_view()(request, str(renkan_guid))
+ return HttpResponseRedirect(request.META.get('HTTP_REFERER', settings.BASE_URL))
+ return HttpResponse('field renkan_guid unknown or bad format', status=400)