diff --git a/TODO b/TODO index b1b10e9..bfdd1d4 100644 --- a/TODO +++ b/TODO @@ -14,7 +14,6 @@ TODO: * Captcha Later: -* Allow adding/editing notes * Usage links in list page? * Avoid page content changing size depending on whether scrollbar is there or not? * Style/extend about page? diff --git a/layerindex/deleteconfirm.html b/layerindex/deleteconfirm.html new file mode 100644 index 0000000..341b91f --- /dev/null +++ b/layerindex/deleteconfirm.html @@ -0,0 +1,34 @@ +{% extends "base.html" %} +{% load i18n %} + +{% comment %} + + layerindex-web - delete confirmation template + + Copyright (C) 2013 Intel Corporation + Licensed under the MIT license, see COPYING.MIT for details + +{% endcomment %} + + + +{% block content %} +{% autoescape on %} + +

Delete {{ object_type }}

+ +

Are you sure you want to delete "{{ object }}"?

+ +
+ {% csrf_token %} + + Cancel +
+ +{% endautoescape %} + +{% endblock %} diff --git a/layerindex/detail.html b/layerindex/detail.html index 27b4ad3..2912211 100644 --- a/layerindex/detail.html +++ b/layerindex/detail.html @@ -33,6 +33,9 @@ {% if perms.layeritem.publish_layer or useredit %} Edit layer + {% if layeritem.layernote_set.count = 0 %} + Add note + {% endif %} {% endif %} {% if layeritem.status = "N" and perms.layeritem.publish_layer %} Publish layer @@ -48,7 +51,13 @@
{% for note in layeritem.layernote_set.all %}
- {{ note.text }} +

{{ note.text }}

+ {% if perms.layeritem.publish_layer or useredit %} +

+ Edit note + Delete note +

+ {% endif %}
{% endfor %}
diff --git a/layerindex/editlayernote.html b/layerindex/editlayernote.html new file mode 100644 index 0000000..4c823d9 --- /dev/null +++ b/layerindex/editlayernote.html @@ -0,0 +1,42 @@ +{% extends "base.html" %} +{% load i18n %} + +{% comment %} + + layerindex-web - add/edit layer note form page template + + Copyright (C) 2013 Intel Corporation + Licensed under the MIT license, see COPYING.MIT for details + +{% endcomment %} + + + +{% block content %} +{% autoescape on %} + +

Add layer note to {{ form.instance.layer.name }}

+ +

This note will appear at the very top of the layer detail page. This would typically be used for important notices, e.g. "This layer is obsolete, use layer xyz instead".

+ +
+ {% csrf_token %} + {{ form.as_p }} + +Cancel +
+ +{% endautoescape %} + +{% endblock %} + + +{% block scripts %} + +{% endblock %} diff --git a/layerindex/forms.py b/layerindex/forms.py index c5ce82c..38e84a8 100644 --- a/layerindex/forms.py +++ b/layerindex/forms.py @@ -4,7 +4,7 @@ # # Licensed under the MIT license, see COPYING.MIT for details -from layerindex.models import LayerItem, LayerMaintainer +from layerindex.models import LayerItem, LayerMaintainer, LayerNote from django import forms from django.core.validators import URLValidator, RegexValidator, email_re from django.forms.models import inlineformset_factory @@ -110,3 +110,13 @@ class SubmitLayerForm(forms.ModelForm): val = URLValidator(verify_exists=False) val(url) return url + + +class EditNoteForm(forms.ModelForm): + class Meta: + model = LayerNote + fields = ('text',) + + def clean_text(self): + text = self.cleaned_data['text'].strip() + return text diff --git a/layerindex/models.py b/layerindex/models.py index fc31fe1..ee5a063 100644 --- a/layerindex/models.py +++ b/layerindex/models.py @@ -7,6 +7,7 @@ from django.db import models from datetime import datetime from django.contrib.auth.models import User +from django.core.urlresolvers import reverse import os.path class LayerItem(models.Model): @@ -88,6 +89,9 @@ class LayerItem(models.Model): return True return False + def get_absolute_url(self): + return reverse('layer_item', args=(self.name,)); + def __unicode__(self): return self.name diff --git a/layerindex/urls.py b/layerindex/urls.py index fa6d900..0ad7546 100644 --- a/layerindex/urls.py +++ b/layerindex/urls.py @@ -7,7 +7,7 @@ from django.conf.urls.defaults import * from django.views.generic import DetailView, ListView from layerindex.models import LayerItem, Recipe -from layerindex.views import LayerListView, RecipeSearchView, MachineSearchView, PlainTextListView, LayerDetailView, edit_layer_view +from layerindex.views import LayerListView, RecipeSearchView, MachineSearchView, PlainTextListView, LayerDetailView, edit_layer_view, edit_layernote_view, delete_layernote_view urlpatterns = patterns('', url(r'^$', @@ -35,6 +35,12 @@ urlpatterns = patterns('', LayerDetailView.as_view( template_name='layerindex/detail.html'), name='layer_item'), + url(r'^layer/(?P[-\w]+)/addnote/$', + edit_layernote_view, {'template_name': 'layerindex/editlayernote.html'}, name="add_layernote"), + url(r'^layer/(?P[-\w]+)/editnote/(?P[-\w]+)/$', + edit_layernote_view, {'template_name': 'layerindex/editlayernote.html'}, name="edit_layernote"), + url(r'^layer/(?P[-\w]+)/deletenote/(?P[-\w]+)/$', + delete_layernote_view, {'template_name': 'layerindex/deleteconfirm.html'}, name="delete_layernote"), url(r'^recipe/(?P[-\w]+)/$', DetailView.as_view( model=Recipe, diff --git a/layerindex/views.py b/layerindex/views.py index 0a55e0b..80d0260 100644 --- a/layerindex/views.py +++ b/layerindex/views.py @@ -9,10 +9,10 @@ from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidde from django.core.urlresolvers import reverse from django.core.exceptions import PermissionDenied from django.template import RequestContext -from layerindex.models import LayerItem, LayerMaintainer, LayerDependency, Recipe, Machine +from layerindex.models import LayerItem, LayerMaintainer, LayerDependency, LayerNote, Recipe, Machine from datetime import datetime from django.views.generic import DetailView, ListView -from layerindex.forms import SubmitLayerForm, LayerMaintainerFormSet +from layerindex.forms import SubmitLayerForm, LayerMaintainerFormSet, EditNoteForm from django.db import transaction from django.contrib.auth.models import User, Permission from django.db.models import Q @@ -23,6 +23,46 @@ import simplesearch import settings +def edit_layernote_view(request, template_name, slug, pk=None): + layeritem = get_object_or_404(LayerItem, name=slug) + if not (request.user.is_authenticated() and (request.user.has_perm('layerindex.publish_layer') or layeritem.user_can_edit(request.user))): + raise PermissionDenied + if pk: + # Edit mode + layernote = get_object_or_404(LayerNote, pk=pk) + else: + # Add mode + layernote = LayerNote() + layernote.layer = layeritem + + if request.method == 'POST': + form = EditNoteForm(request.POST, instance=layernote) + if form.is_valid(): + form.save() + return HttpResponseRedirect(layeritem.get_absolute_url()) + else: + form = EditNoteForm(instance=layernote) + + return render(request, template_name, { + 'form': form, + }) + +def delete_layernote_view(request, template_name, slug, pk): + layeritem = get_object_or_404(LayerItem, name=slug) + if not (request.user.is_authenticated() and (request.user.has_perm('layerindex.publish_layer') or layeritem.user_can_edit(request.user))): + raise PermissionDenied + layernote = get_object_or_404(LayerNote, pk=pk) + if request.method == 'POST': + layernote.delete() + return HttpResponseRedirect(layeritem.get_absolute_url()) + else: + return render(request, template_name, { + 'object': layernote, + 'object_type': layernote._meta.verbose_name, + 'return_url': layeritem.get_absolute_url() + }) + + def edit_layer_view(request, template_name, slug=None): useredit = False if slug: @@ -68,7 +108,7 @@ def edit_layer_view(request, template_name, slug=None): d = Context({ 'user_name': user.get_full_name(), 'layer_name': layeritem.name, - 'layer_url': request.build_absolute_uri(reverse('layer_item', args=(layeritem.name,))), + 'layer_url': request.build_absolute_uri(layeritem.get_absolute_url()), }) subject = '%s - %s' % (settings.SUBMIT_EMAIL_SUBJECT, layeritem.name) from_email = settings.SUBMIT_EMAIL_FROM @@ -105,7 +145,7 @@ def _statuschange(request, name, newstatus): if w.status != newstatus: w.change_status(newstatus, request.user.username) w.save() - return HttpResponseRedirect(reverse('layer_item', args=(name,))) + return HttpResponseRedirect(w.get_absolute_url()) class LayerListView(ListView): context_object_name = 'layer_list'