From d30bb18e43e559d32478a7fb5a11f83ba9b5a3b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Soutad=C3=A9?= Date: Thu, 4 Oct 2012 21:49:33 +0200 Subject: [PATCH 1/5] Add primary comment support --- forms.py | 5 + generators/post.py | 19 +-- models.py | 4 +- templates/category.html | 4 +- templates/edit_comment.html | 9 ++ templates/edit_post.html | 16 +++ templates/generate.html | 2 +- templates/view_blog.html | 4 +- urls.py | 3 + views.py | 236 +++++++++++++++++++++++++++--------- 10 files changed, 232 insertions(+), 70 deletions(-) create mode 100644 templates/edit_comment.html diff --git a/forms.py b/forms.py index 7cc8f75..c9551fe 100644 --- a/forms.py +++ b/forms.py @@ -23,3 +23,8 @@ class UserForm(ModelForm): class Meta: model = User exclude = ('is_staff', 'is_active', 'last_login', 'last_joined', 'user_permissions', 'groups', 'date_joined') + +class CommentForm(ModelForm): + class Meta: + model = Comment + exclude = ('post', 'parent', 'date') diff --git a/generators/post.py b/generators/post.py index 227837b..989a60a 100644 --- a/generators/post.py +++ b/generators/post.py @@ -42,9 +42,7 @@ class Post(Index): node.removeChild(node.childNodes[0]) node.appendChild(dom.createTextNode(post.title)) - def generate(self, blog, src, output): - from dynastie.models import Post, Blog - + def generate(self, blog, src, output, posts): hooks = {'post' : self._createPost, 'meta' : self.createMetas} @@ -52,16 +50,14 @@ class Post(Index): self.addError('No _post.html found, exiting') return self.report + if not os.path.exists(output + '/post'): + os.mkdir(output + '/post') + try: dom = parse(src + '/_post.html') except xml.dom.DOMException as e: self.addError('Error parsing _post.html : ' + e) return self.report - - if not os.path.exists(output + '/post'): - os.mkdir(output + '/post') - - posts = Post.objects.all() for post in posts: #print 'Generate ' + filename @@ -80,6 +76,13 @@ class Post(Index): return self.report + def generate(self, blog, src, output): + from dynastie.models import Post, Blog + + posts = Post.objects.all() + + return self.generate(blog, src, output, hooks, dom, posts) + def createPreview(self, values, dom, root, node): now = datetime.datetime.now() diff --git a/models.py b/models.py index 3c6317b..d0f5049 100644 --- a/models.py +++ b/models.py @@ -257,8 +257,8 @@ class Post(models.Model): class Comment(models.Model): post = models.ForeignKey(Post) - parent = models.ForeignKey('Comment') - date = models.DateField(max_length=255) + parent = models.ForeignKey('self', null=True) + date = models.DateTimeField(max_length=255) author = models.CharField(max_length=255) email = models.EmailField(max_length=255) the_comment = models.TextField(max_length=255) diff --git a/templates/category.html b/templates/category.html index b5a82e2..78453d4 100644 --- a/templates/category.html +++ b/templates/category.html @@ -5,9 +5,11 @@ {% if categories|length == 0 %} Any category available

{% else %} + {% for category in categories %} -
{{ category.id }}{{ category.name }}Edit{% if user.is_superuser %}Delete{% endif %} + {% if user.is_superuser %}{% endif %} {% endfor %} +
{{ category.id }}{{ category.name }}EditDelete
{% endif %} {% if user.is_superuser %}
  • Add a category
  • diff --git a/templates/edit_comment.html b/templates/edit_comment.html new file mode 100644 index 0000000..4cd4a2b --- /dev/null +++ b/templates/edit_comment.html @@ -0,0 +1,9 @@ +{% extends "templates/base.html" %} + +{% block content %} +
    +{% csrf_token %} +{{ form.as_p }} + +
    +{% endblock %} diff --git a/templates/edit_post.html b/templates/edit_post.html index 6a032d9..61584a6 100644 --- a/templates/edit_post.html +++ b/templates/edit_post.html @@ -14,4 +14,20 @@ +
    +{% for comment_list in comments %} +{% for comment in comment_list %} +
    +
    + #{{ comment.id }} {{ comment.author }} {{ comment.email|default:"no mail" }} {{ comment.date|date:"D d M Y" }} delete +
    +
    + {{ comment.the_comment }} +
    +{% endfor %} +{% for comment in comment_list %} +
    +{% endfor %} +
    +{% endfor %} {% endblock %} diff --git a/templates/generate.html b/templates/generate.html index 8fc683d..6c6c82b 100644 --- a/templates/generate.html +++ b/templates/generate.html @@ -24,7 +24,7 @@ {% else %} {% for post in posts %} - + {% endfor %} {% endif %}
    {{ post.id }}{{ post.title }}{{ post.category.name }}{{ post.creation_date }}{{ post.modification_date }}{{ post.published }}{{ post.front_page }}Delete
    {{ post.id }}{{ post.title }}{{ post.category.name }}{{ post.creation_date }}{{ post.modification_date }}{{ post.published }}{{ post.front_page }}{{ comments|hash:cur_id|default_if_none:"0" }} comment{{ comments|hash:cur_id|pluralize }}Delete
    diff --git a/templates/view_blog.html b/templates/view_blog.html index b006f24..dca0a0e 100644 --- a/templates/view_blog.html +++ b/templates/view_blog.html @@ -17,7 +17,9 @@ {% else %} {% for post in posts %} - +{% with post.id as cur_id %} + + {% endwith %} {% endfor %} {% endif %}
    {{ post.id }}{{ post.title }}{{ post.category.name }}{{ post.creation_date }}{{ post.modification_date }}{{ post.published }}{{ post.front_page }}Delete
    {{ post.id }}{{ post.title }}{{ post.category.name }}{{ post.creation_date }}{{ post.modification_date }}{{ post.published }}{{ post.front_page }}{{ comments|hash:cur_id|default_if_none:"0" }} comment{{ comments|hash:cur_id|pluralize }}Delete
    diff --git a/urls.py b/urls.py index 87e3ac4..ac27bf8 100644 --- a/urls.py +++ b/urls.py @@ -28,6 +28,9 @@ urlpatterns = patterns('', url(r'^preview/(\d+)$', 'dynastie.views.preview', name='preview'), url(r'^tinyMCEExternalList/post/add/(\d+)$', 'dynastie.views.tinymcelist_add', name='tinymce'), url(r'^tinyMCEExternalList/post/edit/(\d+)$', 'dynastie.views.tinymcelist_edit', name='tinymce'), + url(r'^comment/add/(\d+)/(\d+)$', 'dynastie.views.add_comment', name='add_comment'), + url(r'^comment/edit/(\d+)$', 'dynastie.views.edit_comment', name='edit_comment'), + url(r'^comment/delete/(\d+)$','dynastie.views.delete_comment',name='delete_comment'), # url(r'^dynastie/', include('dynastie.foo.urls')), # Uncomment the admin/doc line below to enable admin documentation: diff --git a/views.py b/views.py index 10c7694..d046cfe 100644 --- a/views.py +++ b/views.py @@ -4,10 +4,50 @@ from django.shortcuts import render from django.contrib.auth import authenticate, login, logout from django.http import HttpResponseRedirect, HttpResponse, Http404 from django.contrib.auth.decorators import login_required +from django.views.decorators.csrf import csrf_exempt from django.forms.models import inlineformset_factory from dynastie.models import * from dynastie.forms import * +from django.template.defaultfilters import register +from django.template import Variable, VariableDoesNotExist + +@register.filter +def hash(object, attr): + pseudo_context = { 'object' : object } + try: + value = Variable('object.%s' % attr).resolve(pseudo_context) + except VariableDoesNotExist: + value = None + return value + +def have_I_right(request, blog_id=None, post_id=None): + b = None + p = None + + if not post_id is None: + p = Post.objects.filter(pk=post_id) + + if p is None: + raise Http404 + + p = p[0] + + blog_id = p.blog.id + + if not blog_id is None: + if not request.user.is_superuser: + b = Blog.objects.filter(pk=blog_id).filter(writers=request.user.id)[0] + else: + b = Blog.objects.get(pk=post.blog.id) + + if b is None: + raise Http404 + + b = b + + return (b, p) + def index(request): if request.user.is_authenticated(): return HttpResponseRedirect('/blog') @@ -19,7 +59,11 @@ def index(request): login_failed = True else: login(request, user) - return HttpResponseRedirect('/blog') + print request.GET + if 'next' in request.GET: + return HttpResponseRedirect(request.GET['next']) + else: + return HttpResponseRedirect('/blog') c = {'auth_key': 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',\ 'login_failed' : login_failed} @@ -213,7 +257,15 @@ def view_blog(request, blog_id): b = Blog.objects.get(pk=blog_id) form = BlogForm(instance=b) - c = {'blog' : b, 'posts' : posts, 'form' : form} + comments = Comment.objects.all() + dict_comments = {} + for comment in comments: + if not str(comment.post.id) in dict_comments: + dict_comments[str(comment.post.id)] = 1 + else: + dict_comments[str(comment.post.id)] = dict_comments[comment.post.id] + 1 + + c = {'blog' : b, 'posts' : posts, 'form' : form, 'comments' : dict_comments} return render(request, 'templates/view_blog.html', c) @@ -249,10 +301,7 @@ def edit_blog(request, blog_id): @login_required def add_post(request, blog_id): if not request.user.is_superuser: - b = Blog.objects.filter(id=blog_id).filter(writers=request.user.id)[0] - - if b is None: - raise Http404 + (b,) = have_I_right(request, blog_id) if request.method == 'POST': # If the form has been submitted... if 'add' in request.POST: @@ -277,22 +326,11 @@ def add_post(request, blog_id): @login_required def edit_post(request, post_id): + (b, post) = have_I_right(request, None, post_id) post = Post.objects.get(pk=post_id) - if post is None: - raise Http404 - title = post.title - - blog_id = post.blog.id - - if not request.user.is_superuser: - b = Blog.objects.filter(pk=post.blog.id).filter(writers=request.user.id)[0] - - if b is None: - raise Http404 - else: - b = Blog.objects.get(pk=post.blog.id) + blog_id = b.id if request.method == 'POST': # If the form has been submitted... if 'edit' in request.POST: @@ -321,24 +359,32 @@ def edit_post(request, post_id): else: content = 'Empty post' + comments = Comment.objects.filter(post=post).order_by('date') + + comment_list_list = [] + for comment in comments: + print comment.date + try: + if comment.parent.id is None: + comment_list_list.append([comment]) + else: + for comment_list in comment_list_list: + if comment_list[0] == comment.parent: + comment_list[0].append(comment) + break + except Comment.DoesNotExist: + comment_list_list.append([comment]) + return render(request, 'edit_post.html', { 'form': form, 'post_id' : post_id, 'content' : content, - 'blog_id' : blog_id + 'blog_id' : blog_id, 'comments' : comment_list_list }) @login_required def delete_post(request, post_id): - post = Post.objects.get(pk=post_id) + (b, post) = have_I_right(request, None, post_id) - if post is None: - raise Http404 - - b = Blog.objects.filter(writers=request.user.id).filter(pk=post.blog.pk) - - if b is None: - raise Http404 - - blog_id = post.blog.pk + blog_id = b.id post.delete() @@ -346,13 +392,7 @@ def delete_post(request, post_id): @login_required def generate(request, blog_id): - if not request.user.is_superuser: - b = Blog.objects.filter(id=blog_id).filter(writers=request.user.id)[0] - else: - b = Blog.objects.get(pk=blog_id) - - if b is None: - raise Http404 + (b, post) = have_I_right(request, blog_id) b.create_paths() report = b.generate() @@ -374,13 +414,7 @@ def preview(request, blog_id): 'content' : request.POST['content'] } - if not request.user.is_superuser: - b = Blog.objects.filter(id=blog_id).filter(writers=request.user.id)[0] - else: - b = Blog.objects.get(pk=blog_id) - - if b is None: - raise Http404 + (b, ) = have_I_right(request, blog_id) b.create_paths() @@ -435,34 +469,122 @@ def _tinymcelist(request, b, year, month): @login_required def tinymcelist_add(request, blog_id): - from datetime import datetime - now = datetime.now() year = now.year month = now.month - b = Blog.objects.filter(pk=blog_id).filter(writers=request.user.id)[0] - if b is None: + + try: + (b, ) = have_I_right(request, blog_id) + except Http404: return HttpResponse('', content_type='application/x-javascript') ret = _tinymcelist(request, b, year, month) - print 'Ret1 ' + ret - return HttpResponse(ret, content_type='application/x-javascript') @login_required def tinymcelist_edit(request, post_id): - post = Post.objects.filter(pk=post_id) - if post is None: - return HttpResponse('', content_type='application/x-javascript') - b = Blog.objects.filter(pk=post.blog).filter(writers=request.user.id)[0] - if b is None: + try: + (b, post) = have_I_right(request, None, post_id) + except Http404: return HttpResponse('', content_type='application/x-javascript') + year = post.creation_date.year() month = post.creation_date.month() ret = _tinymcelist(request, b, year, month) - print 'Ret2 ' + ret - return HttpResponse(ret, content_type='application/x-javascript') + +@csrf_exempt +def add_comment(request, post_id, parent_id): + from dynastie.generators import post + + ref = request.META['HTTP_REFERER'] + + post = Post(pk=post_id) + if post is None: + return HttpResponseRedirect(ref) + + blog = post.blog + + if parent_id != 0: + parentComment = Comment(pk=parent_id) + if parentComment is None: + return HttpResponseRedirect(ref) + else: + parentComment = None + + if request.POST['author'] == '' or request.POST['the_comment'] == '': + print 'Error on author or the_comment' + return HttpResponseRedirect(ref) + + comment = Comment(post=post, parent=parentComment, date=datetime.now(), author=request.POST['author'],\ + email=request.POST['email'], the_comment=request.POST['the_comment']) + comment.save() + + engine = globals()['post'] + blog.create_paths() + + for name, obj in inspect.getmembers(engine): + if inspect.isclass(obj) and obj.__module__.startswith("dynastie") \ + and obj.__module__.endswith("post"): + e = obj() + content = e.generate(blog, b.src_path, b.output_path, post) + break + + # Send emails + + return HttpResponseRedirect(ref) + + + +@login_required +def edit_comment(request, comment_id): + comment = Comment(pk=comment_id) + if comment is None: + return Http404 + + (b, post) = have_I_right(request, None, comment.post.id) + post_id = post.id + + if request.method == 'POST': # If the form has been submitted... + if 'edit' in request.POST: + form = UserForm(request.POST) # A form bound to the POST data + if form.is_valid(): # All validation rules pass + form = form.save() + user = User.objects.get(pk=form.id) + user.set_password(request.POST['password']) + user.save() + # Process the data in form.cleaned_data + # ... + return HttpResponseRedirect('/post/edit/' + str(post_id)) + else: + return HttpResponseRedirect('/post/edit/' + str(post_id)) + + else: + form = CommentForm() # An unbound form + + return render(request, 'edit_comment.html', { + 'form': form, 'comment':comment + }) + +@login_required +def delete_comment(request, comment_id): + comment = Comment(pk=comment_id) + if comment is None: + return Http404 + + (b, post) = have_I_right(request, None, comment.post.id) + + post_id = post.id + + childs = Comment.objects.filter(parent=comment) + + for child in childs: + child.parent = comment.parent + child.save() + + comment.delete() + + return HttpResponseRedirect('/post/edit/' + str(post_id)) From 76cda686112347ea631bce5230c0388e32b7c2ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Soutad=C3=A9?= Date: Tue, 9 Oct 2012 20:47:12 +0200 Subject: [PATCH 2/5] Set category and tag refers to a Blog --- forms.py | 2 +- generators/post.py | 4 +-- models.py | 2 ++ templates/base.html | 2 +- templates/category.html | 6 ++-- templates/edit_category.html | 6 +--- templates/generate.html | 3 ++ templates/view_blog.html | 1 + urls.py | 14 ++++---- views.py | 65 ++++++++++++++++++++++++------------ 10 files changed, 64 insertions(+), 41 deletions(-) diff --git a/forms.py b/forms.py index c9551fe..51faa40 100644 --- a/forms.py +++ b/forms.py @@ -17,7 +17,7 @@ class PostForm(ModelForm): class CategoryForm(ModelForm): class Meta: model = Category - exclude = ('parent', 'name_slug') + exclude = ('parent', 'name_slug', 'blog') class UserForm(ModelForm): class Meta: diff --git a/generators/post.py b/generators/post.py index 989a60a..e8fd14d 100644 --- a/generators/post.py +++ b/generators/post.py @@ -42,7 +42,7 @@ class Post(Index): node.removeChild(node.childNodes[0]) node.appendChild(dom.createTextNode(post.title)) - def generate(self, blog, src, output, posts): + def _generate(self, blog, src, output, posts): hooks = {'post' : self._createPost, 'meta' : self.createMetas} @@ -81,7 +81,7 @@ class Post(Index): posts = Post.objects.all() - return self.generate(blog, src, output, hooks, dom, posts) + return self._generate(blog, src, output, posts) def createPreview(self, values, dom, root, node): now = datetime.datetime.now() diff --git a/models.py b/models.py index d0f5049..e220d66 100644 --- a/models.py +++ b/models.py @@ -159,6 +159,7 @@ class Category(models.Model): name_slug = models.CharField(max_length=255) parent = models.ForeignKey('self', blank=True, null=True) description = models.TextField(max_length=255, blank=True) + blog = models.ForeignKey(Blog) def slugify(self): name = normalize('NFKD', self.name).encode('ascii', 'ignore').replace(' ', '-').lower() @@ -181,6 +182,7 @@ class Category(models.Model): class Tag(models.Model): name = models.CharField(max_length=255, unique=True) + blog = models.ForeignKey(Blog) class Post(models.Model): title = models.CharField(max_length=255) diff --git a/templates/base.html b/templates/base.html index 13a3063..5ab0eb1 100644 --- a/templates/base.html +++ b/templates/base.html @@ -4,7 +4,7 @@ {% block head %} {% endblock %} - Users Blogs Categories Disconnect

    + Users Blogs Disconnect

    {% block content %} {% endblock %} diff --git a/templates/category.html b/templates/category.html index 78453d4..c851876 100644 --- a/templates/category.html +++ b/templates/category.html @@ -7,12 +7,10 @@ {% else %} {% for category in categories %} - {% if user.is_superuser %}{% endif %} + {% endfor %}
    {{ category.id }}{{ category.name }}EditDelete
    {{ category.id }}{{ category.name }}EditDelete
    {% endif %} -{% if user.is_superuser %} -
  • Add a category
  • -{% endif %} +
  • Add a category
  • {% endblock %} diff --git a/templates/edit_category.html b/templates/edit_category.html index c7a813f..5fba483 100644 --- a/templates/edit_category.html +++ b/templates/edit_category.html @@ -4,10 +4,6 @@
    {% csrf_token %} {{ form.as_p }} -{% if user.is_superuser %} - -{% else %} - -{% endif %} +
    {% endblock %} diff --git a/templates/generate.html b/templates/generate.html index 6c6c82b..dbd51d9 100644 --- a/templates/generate.html +++ b/templates/generate.html @@ -1,6 +1,7 @@ {% extends "templates/base.html" %} {% block content %} +Categories {% if user.is_superuser %}
    {% csrf_token %} @@ -24,7 +25,9 @@ {% else %} {% for post in posts %} +{% with post.id as cur_id %} + {% endwith %} {% endfor %} {% endif %}
    {{ post.id }}{{ post.title }}{{ post.category.name }}{{ post.creation_date }}{{ post.modification_date }}{{ post.published }}{{ post.front_page }}{{ comments|hash:cur_id|default_if_none:"0" }} comment{{ comments|hash:cur_id|pluralize }}Delete
    diff --git a/templates/view_blog.html b/templates/view_blog.html index dca0a0e..38c6f43 100644 --- a/templates/view_blog.html +++ b/templates/view_blog.html @@ -1,6 +1,7 @@ {% extends "templates/base.html" %} {% block content %} +Categories {% if user.is_superuser %} {% csrf_token %} diff --git a/urls.py b/urls.py index ac27bf8..2ef1d75 100644 --- a/urls.py +++ b/urls.py @@ -13,21 +13,21 @@ urlpatterns = patterns('', url(r'^user/add$', 'dynastie.views.add_user', name='add_user'), url(r'^user/edit/(\d+)$', 'dynastie.views.edit_user', name='edit_user'), url(r'^user/(\d+)$', 'dynastie.views.edit_user', name='view_user'), - url(r'^category$', 'dynastie.views.category', name='category'), - url(r'^category/add$', 'dynastie.views.add_category', name='add_category'), + url(r'^category/(\d+)$', 'dynastie.views.category', name='category'), + url(r'^category/add/(\d+)$', 'dynastie.views.add_category', name='add_category'), url(r'^category/edit/(\d+)$', 'dynastie.views.edit_category', name='edit_category'), url(r'^category/delete/(\d+)$', 'dynastie.views.delete_category', name='delete_category'), url(r'^blog$', 'dynastie.views.blog', name='blog'), url(r'^blog/add$', 'dynastie.views.add_blog', name='add_blog'), url(r'^blog/(\d+)$', 'dynastie.views.view_blog', name='view_blog'), url(r'^blog/edit/(\d+)$', 'dynastie.views.edit_blog', name='edit_blog'), - url(r'^post/add/(\d+)$', 'dynastie.views.add_post', name='add_post'), - url(r'^post/edit/(\d+)$', 'dynastie.views.edit_post', name='edit_post'), - url(r'^post/delete/(\d+)$','dynastie.views.delete_post', name='delete_post'), + url(r'^post/add/(\d+)$', 'dynastie.views.add_post', name='add_post'), + url(r'^post/edit/(\d+)$', 'dynastie.views.edit_post', name='edit_post'), + url(r'^post/delete/(\d+)$', 'dynastie.views.delete_post', name='delete_post'), url(r'^generate/(\d+)$', 'dynastie.views.generate', name='generate'), url(r'^preview/(\d+)$', 'dynastie.views.preview', name='preview'), - url(r'^tinyMCEExternalList/post/add/(\d+)$', 'dynastie.views.tinymcelist_add', name='tinymce'), - url(r'^tinyMCEExternalList/post/edit/(\d+)$', 'dynastie.views.tinymcelist_edit', name='tinymce'), + url(r'^tinyMCEExternalList/post/add/(\d+)$', 'dynastie.views.tinymcelist_add', name='tinymce'), + url(r'^tinyMCEExternalList/post/edit/(\d+)$', 'dynastie.views.tinymcelist_edit', name='tinymce'), url(r'^comment/add/(\d+)/(\d+)$', 'dynastie.views.add_comment', name='add_comment'), url(r'^comment/edit/(\d+)$', 'dynastie.views.edit_comment', name='edit_comment'), url(r'^comment/delete/(\d+)$','dynastie.views.delete_comment',name='delete_comment'), diff --git a/views.py b/views.py index d046cfe..ebe6e8a 100644 --- a/views.py +++ b/views.py @@ -14,6 +14,7 @@ from django.template import Variable, VariableDoesNotExist @register.filter def hash(object, attr): + return None pseudo_context = { 'object' : object } try: value = Variable('object.%s' % attr).resolve(pseudo_context) @@ -21,10 +22,13 @@ def hash(object, attr): value = None return value -def have_I_right(request, blog_id=None, post_id=None): +def have_I_right(request, blog_id=None, post_id=None, must_be_superuser=False): b = None p = None + if must_be_superuser and not request.user.is_superuser: + raise Http404 + if not post_id is None: p = Post.objects.filter(pk=post_id) @@ -37,15 +41,16 @@ def have_I_right(request, blog_id=None, post_id=None): if not blog_id is None: if not request.user.is_superuser: - b = Blog.objects.filter(pk=blog_id).filter(writers=request.user.id)[0] + b = Blog.objects.filter(pk=blog_id).filter(writers=request.user.id) + if len(b) == 0: + raise Http404 + b = b[0] else: b = Blog.objects.get(pk=post.blog.id) if b is None: raise Http404 - b = b - return (b, p) def index(request): @@ -143,28 +148,30 @@ def edit_user(request, user_id): return render(request, 'templates/edit_user.html', c) @login_required -def category(request): - categories = Category.objects.all() +def category(request, blog_id): + b = have_I_right(request, blog_id) + + categories = Category.objects.filter(blog_id=blog_id) c = {'categories' : categories} return render(request, 'templates/category.html', c) @login_required -def add_category(request): - if not request.user.is_superuser: - return HttpResponseRedirect('/category') +def add_category(request, blog_id): + b = have_I_right(request, blog_id)[0] if request.method == 'POST': # If the form has been submitted... if 'add' in request.POST: form = CategoryForm(request.POST) # A form bound to the POST data + form.blog = b if form.is_valid(): # All validation rules pass form = form.save() # Process the data in form.cleaned_data # ... - return HttpResponseRedirect('/category') # Redirect after POST + return HttpResponseRedirect('/category/' + str(b.id)) else: - return HttpResponseRedirect('/category') # Redirect after POST + return HttpResponseRedirect('/category/' + str(b.id)) else: form = CategoryForm() # An unbound form @@ -179,16 +186,19 @@ def edit_category(request, category_id): if category is None: raise Http404 + b = have_I_right(request, category.blog.id)[0] + if request.method == 'POST': # If the form has been submitted... if 'cancel' in request.POST: - return HttpResponseRedirect('/category') - if 'edit' in request.POST and request.user.is_superuser: + return HttpResponseRedirect('/category' + str(b.id)) + if 'edit' in request.POST: name = category.name form = CategoryForm(request.POST, instance=category) # A form bound to the POST data if form.is_valid(): # All validation rules pass if request.POST['name'] != name: category.remove() form.save() + return HttpResponseRedirect('/category/' + str(b.id)) else: form = CategoryForm(instance=category) # An unbound form @@ -198,18 +208,17 @@ def edit_category(request, category_id): @login_required def delete_category(request, category_id): - if not request.user.is_superuser: - return HttpResponseRedirect('/category/' + str(category_id)) - category = Category.objects.get(pk=category_id) if category is None: raise Http404 + b = have_I_right(request, category.blog.id)[0] + category.remove() category.delete() - return HttpResponseRedirect('/category') + return HttpResponseRedirect('/category/' + str(b.id)) @login_required def blog(request): @@ -300,8 +309,7 @@ def edit_blog(request, blog_id): @login_required def add_post(request, blog_id): - if not request.user.is_superuser: - (b,) = have_I_right(request, blog_id) + (b,) = have_I_right(request, blog_id) if request.method == 'POST': # If the form has been submitted... if 'add' in request.POST: @@ -401,7 +409,22 @@ def generate(request, blog_id): b = Blog.objects.get(pk=blog_id) form = BlogForm(instance=b) - c = {'blog' : b, 'posts' : posts, 'form' : form, 'report': report} + comments = Comment.objects.filter(post=post).order_by('date') + + comment_list_list = [] + for comment in comments: + try: + if comment.parent.id is None: + comment_list_list.append([comment]) + else: + for comment_list in comment_list_list: + if comment_list[0] == comment.parent: + comment_list[0].append(comment) + break + except Comment.DoesNotExist: + comment_list_list.append([comment]) + + c = {'blog' : b, 'posts' : posts, 'form' : form, 'report': report, 'comments' : comment_list_list} return render(request, 'templates/generate.html', c) @@ -530,7 +553,7 @@ def add_comment(request, post_id, parent_id): if inspect.isclass(obj) and obj.__module__.startswith("dynastie") \ and obj.__module__.endswith("post"): e = obj() - content = e.generate(blog, b.src_path, b.output_path, post) + content = e._generate(blog, b.src_path, b.output_path, post) break # Send emails From 01685868e23e259aae4f828d3952e42ae4b15a0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Soutad=C3=A9?= Date: Thu, 11 Oct 2012 22:26:47 +0200 Subject: [PATCH 3/5] Fix some bugs + add primary comment support --- generators/generator.py | 3 ++ generators/index.py | 18 ++++----- generators/post.py | 43 +++++++++++++++++++++- models.py | 4 +- templates/edit_post.html | 2 +- views.py | 79 +++++++++++++++++++--------------------- 6 files changed, 95 insertions(+), 54 deletions(-) diff --git a/generators/generator.py b/generators/generator.py index 1747bd1..017ad03 100644 --- a/generators/generator.py +++ b/generators/generator.py @@ -142,6 +142,9 @@ class DynastieGenerator: new_elem = self.createElement(dom, node.localName) new_elem.appendChild(content) elem.appendChild(new_elem) + else: + new_elem = node.cloneNode(True) + elem.appendChild(new_elem) else: new_elem = node.cloneNode(False) self.simpleTransform(values, dom, new_elem, node) diff --git a/generators/index.py b/generators/index.py index 3b0814a..3dc1a06 100644 --- a/generators/index.py +++ b/generators/index.py @@ -59,12 +59,12 @@ class Index(DynastieGenerator): new_dom = parseString('') new_node = new_dom.getElementsByTagName('div')[0] root.replaceChild(new_node.cloneNode(True), node) - + def createPost(self, post, dom, post_elem, root): values = {} values['title'] = self.createLinkElem(dom, post.getPath(), post.title) values['author'] = post.author.first_name + ' ' + post.author.last_name - values['date'] = post.creation_date.strftime("%A, %d %B %Y %H:%m") + values['date'] = post.creation_date.strftime('%A, %d %B %Y %H:%m') values['post_content'] = '' blog = post.blog @@ -81,17 +81,17 @@ class Index(DynastieGenerator): f.close() self.simpleTransform(values, dom, post_elem, root) - - content_nodes = post_elem.getElementsByTagName("div") - post_transform = ('post_content') + + content_nodes = post_elem.getElementsByTagName('div') + post_transform = ['post_content'] for content_node in content_nodes: the_class = content_node.getAttribute('class') if not the_class in post_transform: continue - if the_class == 'post_content': - new_node = dom.createTextNode(post_content) - content_node.appendChild(new_node) - + new_node = dom.createTextNode(post_content) + content_node.appendChild(new_node) + + def createPosts(self, posts, dom, root, node): posts_elem = self.createElement(dom, 'posts') for i in range(0, self.posts_per_page): diff --git a/generators/post.py b/generators/post.py index e8fd14d..d5e92cc 100644 --- a/generators/post.py +++ b/generators/post.py @@ -7,6 +7,38 @@ from django.db import models class Post(Index): + def createComments(self, post, dom, post_elem, root): + from dynastie.models import Post, Blog, Comment + + base_url = root.getAttribute('base_url') + add_comment = (root.getAttribute('add_comment') == '1') + + comments = Comment.objects.filter(post=post) + + comment_list_list = [] + for comment in comments: + try: + if comment.parent_id == 0: + comment_list_list.append([comment]) + else: + for comment_list in comment_list_list: + if comment_list[0].id == comment.parent_id: + comment_list.append(comment) + break + except Comment.DoesNotExist: + comment_list_list.append([comment]) + + initial_root_comment = root_comment = self.createElement(dom, 'comments') + for comment_list in comment_list_list: + for comment in comment_list: + comment_element = self.createElement(dom, 'comment') + comment_content = self.createElement(dom, 'comment_content', comment.the_comment) + comment_element.appendChild(comment_content) + root_comment.appendChild(comment_element) + root_comment = comment_element + root_comment = initial_root_comment + post_elem.replaceChild(root_comment, root) + def createMetas(self, post, dom, meta_elem, root): name = root.getAttribute('name') if name is None: @@ -29,7 +61,13 @@ class Post(Index): self.addError('name attribute \'' + name + '\' unknown for dyn:meta' ) def _createPost(self, post, dom, post_elem, root): + import sys, traceback + + if post.id == 122: + print post_elem.toxml() self.createPost(post, dom, post_elem, root) + + # Post are appended by index. Remove template post_nodes = dom.getElementsByTagNameNS(self.URI, 'post') post_elem = post_nodes[0] post_elem.parentNode.removeChild(post_elem) @@ -43,8 +81,10 @@ class Post(Index): node.appendChild(dom.createTextNode(post.title)) def _generate(self, blog, src, output, posts): + import xml hooks = {'post' : self._createPost, - 'meta' : self.createMetas} + 'meta' : self.createMetas, + 'comments' : self.createComments} if not os.path.exists(src + '/_post.html'): self.addError('No _post.html found, exiting') @@ -63,6 +103,7 @@ class Post(Index): #print 'Generate ' + filename nodes = dom.getElementsByTagName("*") nodes[0] = self.parse(src, hooks, post, dom, nodes[0]) + filename = output + '/post/' filename = filename + post.creation_date.strftime("%Y") + '/' + post.creation_date.strftime("%m") + '/' if not os.path.exists(filename): diff --git a/models.py b/models.py index e220d66..a655726 100644 --- a/models.py +++ b/models.py @@ -260,9 +260,9 @@ class Post(models.Model): class Comment(models.Model): post = models.ForeignKey(Post) parent = models.ForeignKey('self', null=True) - date = models.DateTimeField(max_length=255) + date = models.DateTimeField() author = models.CharField(max_length=255) - email = models.EmailField(max_length=255) + email = models.EmailField(max_length=255, blank=True) the_comment = models.TextField(max_length=255) @receiver(post_init, sender=Blog) diff --git a/templates/edit_post.html b/templates/edit_post.html index 61584a6..f6f5037 100644 --- a/templates/edit_post.html +++ b/templates/edit_post.html @@ -9,7 +9,7 @@ {% endblock %} {% block content %} -{% csrf_token %} +{% csrf_token %} {{ form.as_p }} diff --git a/views.py b/views.py index ebe6e8a..8b5874a 100644 --- a/views.py +++ b/views.py @@ -14,7 +14,7 @@ from django.template import Variable, VariableDoesNotExist @register.filter def hash(object, attr): - return None + pseudo_context = { 'object' : object } try: value = Variable('object.%s' % attr).resolve(pseudo_context) @@ -30,13 +30,11 @@ def have_I_right(request, blog_id=None, post_id=None, must_be_superuser=False): raise Http404 if not post_id is None: - p = Post.objects.filter(pk=post_id) + p = Post.objects.get(pk=post_id) if p is None: raise Http404 - p = p[0] - blog_id = p.blog.id if not blog_id is None: @@ -269,10 +267,11 @@ def view_blog(request, blog_id): comments = Comment.objects.all() dict_comments = {} for comment in comments: - if not str(comment.post.id) in dict_comments: - dict_comments[str(comment.post.id)] = 1 + key = comment.post.id + if not key in dict_comments: + dict_comments[key] = 1 else: - dict_comments[str(comment.post.id)] = dict_comments[comment.post.id] + 1 + dict_comments[key] = dict_comments[key] + 1 c = {'blog' : b, 'posts' : posts, 'form' : form, 'comments' : dict_comments} @@ -347,8 +346,8 @@ def edit_post(request, post_id): if form.is_valid(): # All validation rules pass if title != request.POST['title']: post.remove() - post.createPost(request.POST['content']) form.save() + post.createPost(request.POST['content']) # Process the data in form.cleaned_data # ... return HttpResponseRedirect('/blog/' + str(blog_id)) # Redirect after POST @@ -377,8 +376,8 @@ def edit_post(request, post_id): comment_list_list.append([comment]) else: for comment_list in comment_list_list: - if comment_list[0] == comment.parent: - comment_list[0].append(comment) + if comment_list[0].id == comment.parent_id: + comment_list.append(comment) break except Comment.DoesNotExist: comment_list_list.append([comment]) @@ -409,22 +408,16 @@ def generate(request, blog_id): b = Blog.objects.get(pk=blog_id) form = BlogForm(instance=b) - comments = Comment.objects.filter(post=post).order_by('date') - - comment_list_list = [] + comments = Comment.objects.all() + dict_comments = {} for comment in comments: - try: - if comment.parent.id is None: - comment_list_list.append([comment]) - else: - for comment_list in comment_list_list: - if comment_list[0] == comment.parent: - comment_list[0].append(comment) - break - except Comment.DoesNotExist: - comment_list_list.append([comment]) + key = comment.post.id + if not key in dict_comments: + dict_comments[key] = 1 + else: + dict_comments[key] = dict_comments[key] + 1 - c = {'blog' : b, 'posts' : posts, 'form' : form, 'report': report, 'comments' : comment_list_list} + c = {'blog' : b, 'posts' : posts, 'form' : form, 'report': report, 'comments' : dict_comments} return render(request, 'templates/generate.html', c) @@ -525,14 +518,20 @@ def add_comment(request, post_id, parent_id): ref = request.META['HTTP_REFERER'] - post = Post(pk=post_id) + post = Post.objects.get(pk=post_id) if post is None: + print 'no post' return HttpResponseRedirect(ref) - blog = post.blog + blog = Blog.objects.get(pk=post.blog_id) + if blog is None: + print 'no blog ' + str(post.blog.id) + return HttpResponseRedirect(ref) + + parent_id = int(parent_id) if parent_id != 0: - parentComment = Comment(pk=parent_id) + parentComment = Comment.objects.get(pk=parent_id) if parentComment is None: return HttpResponseRedirect(ref) else: @@ -549,11 +548,12 @@ def add_comment(request, post_id, parent_id): engine = globals()['post'] blog.create_paths() + post_list = [post] for name, obj in inspect.getmembers(engine): if inspect.isclass(obj) and obj.__module__.startswith("dynastie") \ and obj.__module__.endswith("post"): e = obj() - content = e._generate(blog, b.src_path, b.output_path, post) + content = e._generate(blog, blog.src_path, blog.output_path, post_list) break # Send emails @@ -564,21 +564,19 @@ def add_comment(request, post_id, parent_id): @login_required def edit_comment(request, comment_id): - comment = Comment(pk=comment_id) + comment = Comment.objects.get(pk=comment_id) + if comment is None: return Http404 - (b, post) = have_I_right(request, None, comment.post.id) - post_id = post.id + (b, post) = have_I_right(request, None, comment.post_id) + post_id = comment.post_id if request.method == 'POST': # If the form has been submitted... if 'edit' in request.POST: - form = UserForm(request.POST) # A form bound to the POST data + form = CommentForm(request.POST, instance=comment) # A form bound to the POST data if form.is_valid(): # All validation rules pass form = form.save() - user = User.objects.get(pk=form.id) - user.set_password(request.POST['password']) - user.save() # Process the data in form.cleaned_data # ... return HttpResponseRedirect('/post/edit/' + str(post_id)) @@ -586,7 +584,7 @@ def edit_comment(request, comment_id): return HttpResponseRedirect('/post/edit/' + str(post_id)) else: - form = CommentForm() # An unbound form + form = CommentForm(instance=comment) # An unbound form return render(request, 'edit_comment.html', { 'form': form, 'comment':comment @@ -594,14 +592,13 @@ def edit_comment(request, comment_id): @login_required def delete_comment(request, comment_id): - comment = Comment(pk=comment_id) + comment = Comment.objects.get(pk=comment_id) if comment is None: return Http404 - (b, post) = have_I_right(request, None, comment.post.id) - - post_id = post.id - + (b, post) = have_I_right(request, None, comment.post_id) + post_id = comment.post_id + childs = Comment.objects.filter(parent=comment) for child in childs: From 3c3070cf315a4a1421bf899f378c2c0d202bd467 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Soutad=C3=A9?= Date: Tue, 16 Oct 2012 22:06:33 +0200 Subject: [PATCH 4/5] Need to return objects in generator hooks Add dyn:comments and dyn:replace support --- generators/archive.py | 2 ++ generators/category.py | 1 + generators/generator.py | 12 +++---- generators/index.py | 12 +++++-- generators/post.py | 74 +++++++++++++++++++++++++++++++++++------ models.py | 2 +- views.py | 9 +++-- 7 files changed, 88 insertions(+), 24 deletions(-) diff --git a/generators/archive.py b/generators/archive.py index 35621a0..0ffae95 100644 --- a/generators/archive.py +++ b/generators/archive.py @@ -19,6 +19,8 @@ class Archive(Index): if node.hasAttribute('year'): self.replaceByText(dom, root, node, str(self.cur_year)) + return None + def createArchives(self, src, output, dom, hooks, posts): filename = self.filename + '.html' self.nb_pages = 0 diff --git a/generators/category.py b/generators/category.py index 9bf3e6c..3c3aff2 100644 --- a/generators/category.py +++ b/generators/category.py @@ -19,6 +19,7 @@ class Category(Index): self.replaceByText(dom, root, node, self.cur_category.name) if node.hasAttribute('description'): self.replaceByText(dom, root, node, self.cur_category.description) + return None def generate(self, blog, src, output): from dynastie.models import Post, Blog, Category diff --git a/generators/generator.py b/generators/generator.py index 017ad03..d99de02 100644 --- a/generators/generator.py +++ b/generators/generator.py @@ -141,14 +141,13 @@ class DynastieGenerator: else: new_elem = self.createElement(dom, node.localName) new_elem.appendChild(content) - elem.appendChild(new_elem) else: - new_elem = node.cloneNode(True) - elem.appendChild(new_elem) + new_elem = node.cloneNode(False) + self.simpleTransform(values, dom, new_elem, node) else: new_elem = node.cloneNode(False) self.simpleTransform(values, dom, new_elem, node) - elem.appendChild(new_elem) + elem.appendChild(new_elem) def replaceByText(self, dom, root, node, content): new_node = dom.createTextNode(content) @@ -158,10 +157,9 @@ class DynastieGenerator: for node in root.childNodes: if node.prefix == 'dyn': if node.localName in hooks: - hooks[node.localName](posts, dom, root, node) - if node.hasChildNodes(): + node = hooks[node.localName](posts, dom, root, node) + if not node is None and node.hasChildNodes(): self._parse(hooks, posts, dom, node) - return def parse(self, src, hooks, posts, dom, root): bases = dom.getElementsByTagNameNS(self.URI, 'base') diff --git a/generators/index.py b/generators/index.py index 3dc1a06..ccdfac1 100644 --- a/generators/index.py +++ b/generators/index.py @@ -17,7 +17,7 @@ class Index(DynastieGenerator): def createNavigation(self, posts, dom, root, node): if self.nb_pages == 0 or self.nb_pages == 1: - return '' + return None if self.dirname != '': if self.dirname.startswith('/'): @@ -58,8 +58,11 @@ class Index(DynastieGenerator): new_dom = parseString('') new_node = new_dom.getElementsByTagName('div')[0] - root.replaceChild(new_node.cloneNode(True), node) - + res = new_node.cloneNode(True) + root.replaceChild(res, node) + + return res + def createPost(self, post, dom, post_elem, root): values = {} values['title'] = self.createLinkElem(dom, post.getPath(), post.title) @@ -106,6 +109,7 @@ class Index(DynastieGenerator): if self.cur_post == len(posts): break root.replaceChild(posts_elem, node) + return posts_elem def createRecents(self, posts, dom, root, node): if self.cur_post == len(posts): @@ -132,6 +136,8 @@ class Index(DynastieGenerator): recents_elem.appendChild(list_elem) root.replaceChild(recents_elem, node) + + return recents_elem def generate(self, blog, src, output): from dynastie.models import Post, Blog diff --git a/generators/post.py b/generators/post.py index d5e92cc..03010ac 100644 --- a/generators/post.py +++ b/generators/post.py @@ -7,22 +7,62 @@ from django.db import models class Post(Index): + cur_comment = None + comment_index = {} + + def createReplace(self, post, dom, root, replace_elem): + if not replace_elem.hasAttribute('div_name'): + self.addError('No attribute div_name for a replace tag') + return + + div_element = replace_elem.cloneNode(True) + div_element.tagName = replace_elem.getAttribute('div_name') + div_element.removeAttribute('div_name') + for key,value in replace_elem.attributes.items(): + if key == 'div_name': continue + value = value.replace('dyn:post_id', str(post.id)) + if self.cur_comment is None: + value = value.replace('dyn:comment_id', '0') + else: + value = value.replace('dyn:comment_id', str(self.comment_index[self.cur_comment.id])) + if self.cur_comment is None or self.cur_comment.parent is None: + value = value.replace('dyn:comment_parent_id', '0') + else: + value = value.replace('dyn:comment_parent_id', str(self.cur_comment.id)) + + div_element.setAttribute(key, value) + + root.replaceChild(div_element, replace_elem) + return div_element + + def createComment(self, comment, dom, comment_elem, root): + values = {} + values['comment_id'] = str(comment.id) + values['comment_author'] = comment.author + values['comment_date'] = comment.date.strftime('%d %B %Y %H:%m') + values['comment_content'] = comment.the_comment + + self.simpleTransform(values, dom, comment_elem, root) + def createComments(self, post, dom, post_elem, root): from dynastie.models import Post, Blog, Comment - base_url = root.getAttribute('base_url') - add_comment = (root.getAttribute('add_comment') == '1') + comments = Comment.objects.filter(post=post).order_by('date') - comments = Comment.objects.filter(post=post) + cur_comment = None + comment_index = {} comment_list_list = [] + index = 1 for comment in comments: + self.comment_index[comment.id] = index + index = index + 1 try: - if comment.parent_id == 0: + if comment.parent is None: comment_list_list.append([comment]) else: for comment_list in comment_list_list: - if comment_list[0].id == comment.parent_id: + if comment_list[0].id == comment.parent.id: comment_list.append(comment) break except Comment.DoesNotExist: @@ -31,13 +71,20 @@ class Post(Index): initial_root_comment = root_comment = self.createElement(dom, 'comments') for comment_list in comment_list_list: for comment in comment_list: + self.cur_comment = comment comment_element = self.createElement(dom, 'comment') - comment_content = self.createElement(dom, 'comment_content', comment.the_comment) - comment_element.appendChild(comment_content) + self.createComment(comment, dom, comment_element, root) root_comment.appendChild(comment_element) root_comment = comment_element root_comment = initial_root_comment - post_elem.replaceChild(root_comment, root) + + # Empty tag seems to crap rendering + if len(comment_list_list) == 0: + post_elem.removeChild(root) + return None + else: + post_elem.replaceChild(root_comment, root) + return root_comment def createMetas(self, post, dom, meta_elem, root): name = root.getAttribute('name') @@ -57,14 +104,14 @@ class Post(Index): if not new_elem is None: root.parentNode.replaceChild(new_elem, root) + return new_elem else: self.addError('name attribute \'' + name + '\' unknown for dyn:meta' ) + return None def _createPost(self, post, dom, post_elem, root): import sys, traceback - if post.id == 122: - print post_elem.toxml() self.createPost(post, dom, post_elem, root) # Post are appended by index. Remove template @@ -80,11 +127,14 @@ class Post(Index): node.removeChild(node.childNodes[0]) node.appendChild(dom.createTextNode(post.title)) + return node + def _generate(self, blog, src, output, posts): import xml hooks = {'post' : self._createPost, 'meta' : self.createMetas, - 'comments' : self.createComments} + 'comments' : self.createComments, + 'replace' : self.createReplace} if not os.path.exists(src + '/_post.html'): self.addError('No _post.html found, exiting') @@ -149,6 +199,8 @@ class Post(Index): post_elem = post_nodes[0] post_elem.parentNode.removeChild(post_elem) + return post_elem + def preview(self, src, values): from dynastie.models import Blog diff --git a/models.py b/models.py index a655726..9f610d1 100644 --- a/models.py +++ b/models.py @@ -259,7 +259,7 @@ class Post(models.Model): class Comment(models.Model): post = models.ForeignKey(Post) - parent = models.ForeignKey('self', null=True) + parent = models.ForeignKey('self', null=True, blank=True) date = models.DateTimeField() author = models.CharField(max_length=255) email = models.EmailField(max_length=255, blank=True) diff --git a/views.py b/views.py index 8b5874a..a8a16aa 100644 --- a/views.py +++ b/views.py @@ -599,10 +599,15 @@ def delete_comment(request, comment_id): (b, post) = have_I_right(request, None, comment.post_id) post_id = comment.post_id - childs = Comment.objects.filter(parent=comment) + childs = Comment.objects.filter(parent=comment.id) + + try: + parent = comment.parent + except: + parent = None for child in childs: - child.parent = comment.parent + child.parent = parent child.save() comment.delete() From b87a78df594e9b40960ab6ca82720cad7747b8d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Soutad=C3=A9?= Date: Sat, 20 Oct 2012 19:05:29 +0200 Subject: [PATCH 5/5] Finalize comments --- generators/post.py | 68 ++++++++++++++++++++----------------- models.py | 3 +- templates/edit_post.html | 7 +--- tree.py | 21 ++++++++++++ views.py | 73 +++++++++++++++++++++++++++++----------- 5 files changed, 115 insertions(+), 57 deletions(-) create mode 100644 tree.py diff --git a/generators/post.py b/generators/post.py index 03010ac..5d39d79 100644 --- a/generators/post.py +++ b/generators/post.py @@ -4,6 +4,7 @@ from xml.dom.minidom import parse, parseString from dynastie.generators.generator import DynastieGenerator, StrictUTF8Writer from dynastie.generators.index import Index from django.db import models +from dynastie.tree import TreeNode class Post(Index): @@ -21,14 +22,14 @@ class Post(Index): for key,value in replace_elem.attributes.items(): if key == 'div_name': continue value = value.replace('dyn:post_id', str(post.id)) + if self.cur_comment is None: + value = value.replace('dyn:comment_index', '0') + else: + value = value.replace('dyn:comment_index', str(self.comment_index[self.cur_comment.id])) if self.cur_comment is None: value = value.replace('dyn:comment_id', '0') else: - value = value.replace('dyn:comment_id', str(self.comment_index[self.cur_comment.id])) - if self.cur_comment is None or self.cur_comment.parent is None: - value = value.replace('dyn:comment_parent_id', '0') - else: - value = value.replace('dyn:comment_parent_id', str(self.cur_comment.id)) + value = value.replace('dyn:comment_id', str(self.cur_comment.id)) div_element.setAttribute(key, value) @@ -37,13 +38,24 @@ class Post(Index): def createComment(self, comment, dom, comment_elem, root): values = {} - values['comment_id'] = str(comment.id) + values['comment_index'] = str(self.comment_index[comment.id]) values['comment_author'] = comment.author values['comment_date'] = comment.date.strftime('%d %B %Y %H:%m') values['comment_content'] = comment.the_comment self.simpleTransform(values, dom, comment_elem, root) + def _createComments(self, rootNode, post, dom, root_comment, root): + self.cur_comment = rootNode.value + comment_element = self.createElement(dom, 'comment') + self.createComment(self.cur_comment, dom, comment_element, root) + root_comment.appendChild(comment_element) + # Parse inner HTML + self._parse(self.hooks, post, dom, comment_element) + + for commentNode in rootNode.childs: + self._createComments(commentNode, post, dom, comment_element, root) + def createComments(self, post, dom, post_elem, root): from dynastie.models import Post, Blog, Comment @@ -51,35 +63,29 @@ class Post(Index): cur_comment = None comment_index = {} - - comment_list_list = [] index = 1 + + rootNode = TreeNode('', '') for comment in comments: self.comment_index[comment.id] = index index = index + 1 - try: - if comment.parent is None: - comment_list_list.append([comment]) + tnode = TreeNode(comment.id, comment) + if comment.parent is None: + rootNode.addChildNode(tnode) + else: + temp = rootNode.find(comment.parent.id) + if temp is None: + self.addWarning('Error with comments chain') + rootNode.addChildNode(tnode) else: - for comment_list in comment_list_list: - if comment_list[0].id == comment.parent.id: - comment_list.append(comment) - break - except Comment.DoesNotExist: - comment_list_list.append([comment]) - + temp.addChildNode(tnode) + initial_root_comment = root_comment = self.createElement(dom, 'comments') - for comment_list in comment_list_list: - for comment in comment_list: - self.cur_comment = comment - comment_element = self.createElement(dom, 'comment') - self.createComment(comment, dom, comment_element, root) - root_comment.appendChild(comment_element) - root_comment = comment_element - root_comment = initial_root_comment + for tnode in rootNode.childs: + self._createComments(tnode, post, dom, root_comment, root) # Empty tag seems to crap rendering - if len(comment_list_list) == 0: + if len(rootNode.childs) == 0: post_elem.removeChild(root) return None else: @@ -131,7 +137,7 @@ class Post(Index): def _generate(self, blog, src, output, posts): import xml - hooks = {'post' : self._createPost, + self.hooks = {'post' : self._createPost, 'meta' : self.createMetas, 'comments' : self.createComments, 'replace' : self.createReplace} @@ -152,7 +158,7 @@ class Post(Index): for post in posts: #print 'Generate ' + filename nodes = dom.getElementsByTagName("*") - nodes[0] = self.parse(src, hooks, post, dom, nodes[0]) + nodes[0] = self.parse(src, self.hooks, post, dom, nodes[0]) filename = output + '/post/' filename = filename + post.creation_date.strftime("%Y") + '/' + post.creation_date.strftime("%m") + '/' @@ -204,7 +210,7 @@ class Post(Index): def preview(self, src, values): from dynastie.models import Blog - hooks = {'post' : self.createPreview} + self.hooks = {'post' : self.createPreview} if not os.path.exists(src + '/_post.html'): self.addError('No _post.html found, exiting') @@ -223,7 +229,7 @@ class Post(Index): return self.report nodes = dom.getElementsByTagName("*") - nodes[0] = self.parse(src, hooks, values, dom, nodes[0]) + nodes[0] = self.parse(src, self.hooks, values, dom, nodes[0]) writer = StrictUTF8Writer() nodes[0].writexml(writer) diff --git a/models.py b/models.py index 9f610d1..6e067c1 100644 --- a/models.py +++ b/models.py @@ -141,7 +141,7 @@ class Blog(models.Model): if not inspect.ismodule(engine): continue for name, obj in inspect.getmembers(engine): - if inspect.isclass(obj) and obj.__module__.startswith("dynastie"): + if inspect.isclass(obj) and obj.__module__.startswith("dynastie.generators"): if obj.__module__ in generated: continue e = obj() r = e.generate(self, self.src_path, self.output_path) @@ -264,6 +264,7 @@ class Comment(models.Model): author = models.CharField(max_length=255) email = models.EmailField(max_length=255, blank=True) the_comment = models.TextField(max_length=255) + ip = models.GenericIPAddressField() @receiver(post_init, sender=Blog) def delete_blog_signal(sender, **kwargs): diff --git a/templates/edit_post.html b/templates/edit_post.html index f6f5037..7fe89ee 100644 --- a/templates/edit_post.html +++ b/templates/edit_post.html @@ -15,8 +15,7 @@
    -{% for comment_list in comments %} -{% for comment in comment_list %} +{% for comment in comments %}
    #{{ comment.id }} {{ comment.author }} {{ comment.email|default:"no mail" }} {{ comment.date|date:"D d M Y" }} delete @@ -25,9 +24,5 @@ {{ comment.the_comment }}
    {% endfor %} -{% for comment in comment_list %} -
    -{% endfor %}
    -{% endfor %} {% endblock %} diff --git a/tree.py b/tree.py new file mode 100644 index 0000000..7d1c127 --- /dev/null +++ b/tree.py @@ -0,0 +1,21 @@ + + +class TreeNode(): + + def __init__(self, key, value): + self.childs = [] + self.key = key + self.value = value + + def addChildNode(self, node): + self.childs.append(node) + + def hasChilds(self): + return (len(self.childs) > 0) + + def find(self, key): + if key == self.key: return self + for child in self.childs: + r = child.find(key) + if r != None: return r + return None diff --git a/views.py b/views.py index a8a16aa..3046486 100644 --- a/views.py +++ b/views.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import os from datetime import datetime, date, time from django.shortcuts import render @@ -6,6 +7,9 @@ from django.http import HttpResponseRedirect, HttpResponse, Http404 from django.contrib.auth.decorators import login_required from django.views.decorators.csrf import csrf_exempt from django.forms.models import inlineformset_factory +from django.core import mail +from django.core.mail import EmailMultiAlternatives + from dynastie.models import * from dynastie.forms import * @@ -62,7 +66,6 @@ def index(request): login_failed = True else: login(request, user) - print request.GET if 'next' in request.GET: return HttpResponseRedirect(request.GET['next']) else: @@ -367,24 +370,13 @@ def edit_post(request, post_id): content = 'Empty post' comments = Comment.objects.filter(post=post).order_by('date') - - comment_list_list = [] + comment_list = [] for comment in comments: - print comment.date - try: - if comment.parent.id is None: - comment_list_list.append([comment]) - else: - for comment_list in comment_list_list: - if comment_list[0].id == comment.parent_id: - comment_list.append(comment) - break - except Comment.DoesNotExist: - comment_list_list.append([comment]) + comment_list.append(comment) return render(request, 'edit_post.html', { 'form': form, 'post_id' : post_id, 'content' : content, - 'blog_id' : blog_id, 'comments' : comment_list_list + 'blog_id' : blog_id, 'comments' : comment_list }) @login_required @@ -437,7 +429,7 @@ def preview(request, blog_id): engine = globals()['post'] for name, obj in inspect.getmembers(engine): - if inspect.isclass(obj) and obj.__module__.startswith("dynastie") \ + if inspect.isclass(obj) and obj.__module__.startswith("dynastie.generators") \ and obj.__module__.endswith("post"): e = obj() content = e.preview(b.src_path, values) @@ -542,7 +534,7 @@ def add_comment(request, post_id, parent_id): return HttpResponseRedirect(ref) comment = Comment(post=post, parent=parentComment, date=datetime.now(), author=request.POST['author'],\ - email=request.POST['email'], the_comment=request.POST['the_comment']) + email=request.POST['email'], the_comment=request.POST['the_comment'], ip=request.META['REMOTE_ADDR']) comment.save() engine = globals()['post'] @@ -550,15 +542,58 @@ def add_comment(request, post_id, parent_id): post_list = [post] for name, obj in inspect.getmembers(engine): - if inspect.isclass(obj) and obj.__module__.startswith("dynastie") \ + if inspect.isclass(obj) and obj.__module__.startswith("dynastie.generators") \ and obj.__module__.endswith("post"): e = obj() content = e._generate(blog, blog.src_path, blog.output_path, post_list) break # Send emails + emails = {} + comments = Comment.objects.filter(post=post).order_by('date') + comment_index = str(len(comments)) + for comment in comments: + email = comment.email + if email != '' and not email in emails: + emails[email] = comment.author - return HttpResponseRedirect(ref) + if len(emails) > 0: + connection = mail.get_connection(fail_silently=True) + connection.open() + + messages = [] + subject = '[%s] Nouveau commentaire pour l\'article "%s"' % (blog.name, post.title) + + for email,author in emails.items(): + text_body = u'Bonjour %s,\n\nUn nouveau commentaire a été posté pour l\'article "%s".\n\n' % (author, post.title) + text_body += u'Pour le consulter, rendez vous sur http://%s%s/#comment_%s\n\n----------------\n\n' % (blog.name, post.getPath(), comment_index) + text_body += comment.the_comment + text_body += '\n' + + html_body = u'' + html_body += u'Bonjour %s,

    Un nouveau commentaire a été posté pour l\'article "%s".

    ' % (author, post.title) + html_body = html_body + u'Pour le consulter, rendez vous sur http://%s/%s#comment_%s

    ----------------
    '  % (blog.name, post.getPath(), comment_index, blog.name, post.getPath(), comment_index)
    +            c = comment.the_comment
    +            # Avoid script injection
    +            c = c.replace('
    ', '<pre>')
    +            c = c.replace('
    ', '</pre>') + html_body += c + '
    ' + html_body += '' + + msg = EmailMultiAlternatives(subject, text_body, 'no-reply@%s' % blog.name , [email]) + msg.attach_alternative(html_body, "text/html") + messages.append(msg) + + connection.send_messages(messages) + connection.close() + + response = HttpResponseRedirect(ref) + + response.set_cookie('author', request.POST['author'], domain=blog.name, secure=True, httponly=False); + if request.POST['email'] != '': + response.set_cookie('email', request.POST['email'], domain=blog.name, secure=True, httponly=False); + + return response