Dynastie/views.py
Grégory Soutadé 0150b9f6cd Add verifications during blog generation when user/category is suppressed
Delete comments when a post is deleted
Forgot to set email input as hidden in comment responses
Forgot to setup cache for post comment generation
2013-01-29 18:51:23 +01:00

793 lines
23 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding: utf-8 -*-
import os
from datetime import datetime, date, time
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 django.core import mail
from django.core.mail import EmailMultiAlternatives
from dynastie.models import *
from dynastie.forms import *
from dynastie.search 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, 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.get(pk=post_id)
if p is None:
raise Http404
blog_id = p.blog.id
if not blog_id is None:
if not request.user.is_superuser:
b = Blog.objects.filter(pk=blog_id, writers=request.user.id)
if len(b) == 0:
raise Http404
b = b[0]
else:
b = Blog.objects.get(pk=blog_id)
if b is None:
raise Http404
return (b, p)
def createNavigationBar(blog_id, cur_page, nb_pages):
if nb_pages == 0: return ''
navigation_bar = ''
if cur_page == 0:
navigation_bar += '<< <'
else:
navigation_bar += '<a href="/blog/%d?page=0">&lt;&lt;</a> ' % blog_id
navigation_bar += '<a href="/blog/%d?page=%d">&lt;</a> ' % (blog_id, cur_page-1)
for i in range(nb_pages+1):
if i == cur_page:
navigation_bar += ' %d' % (i+1)
else:
navigation_bar += ' <a href="/blog/%d?page=%d">%d</a>' % (blog_id, i, i+1)
if cur_page == nb_pages:
navigation_bar += ' > >>'
else:
navigation_bar += ' <a href="/blog/%d?page=%d">&gt;</a>' % (blog_id, cur_page+1)
navigation_bar += ' <a href="/blog/%d?page=%d">&gt;&gt;</a>' % (blog_id, nb_pages)
return navigation_bar
def index(request):
if request.user.is_authenticated():
return HttpResponseRedirect('/blog')
login_failed = False
if 'login' in request.POST:
user = authenticate(username=request.POST['login'], password=request.POST['password'])
if user is None:
login_failed = True
else:
login(request, user)
if 'next' in request.GET:
return HttpResponseRedirect(request.GET['next'])
else:
return HttpResponseRedirect('/blog')
c = {'login_failed' : login_failed}
return render(request, 'templates/login.html', c)
def disconnect(request):
logout(request)
c = {'login_failed' : False}
return HttpResponseRedirect('/')
@login_required
def user(request):
users = User.objects.all()
c = {'users' : users}
return render(request, 'templates/user.html', c)
@login_required
def add_user(request):
if not request.user.is_superuser:
return HttpResponseRedirect('/user')
if request.method == 'POST':
if 'add' in request.POST:
form = UserForm(request.POST)
if form.is_valid():
form = form.save()
user = User.objects.get(pk=form.id)
user.set_password(request.POST['password'])
user.save()
return HttpResponseRedirect('/user')
else:
return HttpResponseRedirect('/user')
else:
form = UserForm()
return render(request, 'add_user.html', {'form': form})
@login_required
def edit_user(request, user_id):
user = User.objects.get(pk=user_id)
if user is None:
raise Http404
edited = False
if request.method == 'POST':
if int(user_id) != int(request.user.id) and (not request.user.is_superuser):
return HttpResponseRedirect('/user')
if 'edit' in request.POST:
form = UserForm(request.POST, instance=user, initial={'password':''})
if form.is_valid():
form.save()
if request.POST['password'] != '':
user.set_password(request.POST['password'])
user.save()
edited = True
else:
if 'delete' in request.POST and request.user.is_superuser:
User.objects.get(pk=user_id).delete()
return HttpResponseRedirect('/user')
if 'cancel' in request.POST:
return HttpResponseRedirect('/user')
else:
form = UserForm(instance=user, initial={'password':''})
c = {'user_to_edit' : user, 'form' : form, 'edited' : edited}
return render(request, 'templates/edit_user.html', c)
@login_required
def category(request, blog_id):
b,_ = have_I_right(request, blog_id)
categories = Category.objects.filter(blog_id=blog_id)
c = {'categories' : categories, 'blog' : b}
return render(request, 'templates/category.html', c)
@login_required
def add_category(request, blog_id):
b,_ = have_I_right(request, blog_id)
if request.method == 'POST':
if 'add' in request.POST:
form = CategoryForm(request.POST)
form.blog = b
if form.is_valid():
form = form.save()
return HttpResponseRedirect('/category/' + str(b.id))
else:
return HttpResponseRedirect('/category/' + str(b.id))
else:
form = CategoryForm()
return render(request, 'add_category.html', {'form': form})
@login_required
def edit_category(request, category_id):
category = Category.objects.get(pk=category_id)
if category is None:
raise Http404
b,_ = have_I_right(request, category.blog.id)
if request.method == 'POST':
if 'cancel' in request.POST:
return HttpResponseRedirect('/category/' + str(b.id))
if 'edit' in request.POST:
name = category.name
name = name.strip()
form = CategoryForm(request.POST, instance=category)
if form.is_valid():
if request.POST['name'] != name:
category.remove()
form.save()
return HttpResponseRedirect('/category/' + str(b.id))
else:
form = CategoryForm(instance=category)
c = {'category' : category, 'form' : form}
return render(request, 'templates/edit_category.html', c)
@login_required
def delete_category(request, category_id):
category = Category.objects.get(pk=category_id)
if category is None:
raise Http404
b,_ = have_I_right(request, category.blog.id)
category.delete()
return HttpResponseRedirect('/category/' + str(b.id))
@login_required
def tag(request, blog_id):
b,_ = have_I_right(request, blog_id)
tags = Tag.objects.filter(blog_id=blog_id)
c = {'tags' : tags, 'blog' : b}
return render(request, 'templates/tag.html', c)
@login_required
def edit_tag(request, tag_id):
tag = Tag.objects.get(pk=tag_id)
if tag is None:
raise Http404
b,_ = have_I_right(request, tag.blog.id)
if request.method == 'POST':
if 'cancel' in request.POST:
return HttpResponseRedirect('/tag/' + str(b.id))
if 'edit' in request.POST:
name = tag.name
form = TagForm(request.POST, instance=tag)
if form.is_valid():
if request.POST['name'] != name:
tag.remove()
form.save()
return HttpResponseRedirect('/tag/' + str(b.id))
else:
form = TagForm(instance=tag)
c = {'tag' : tag, 'form' : form}
return render(request, 'templates/edit_tag.html', c)
@login_required
def delete_tag(request, tag_id):
tag = Tag.objects.get(pk=tag_id)
if tag is None:
raise Http404
b,_ = have_I_right(request, tag.blog.id)
tag.delete()
return HttpResponseRedirect('/tag/' + str(b.id))
@login_required
def blog(request):
if request.user.is_superuser:
b = Blog.objects.all()
else:
b = Blog.objects.filter(writers=request.user.id)
c = {'blogs' : b}
return render(request, 'templates/blog.html', c)
@login_required
def add_blog(request):
if not request.user.is_superuser:
return HttpResponseRedirect('/blog')
if request.method == 'POST':
if 'add' in request.POST:
form = BlogForm(request.POST)
if form.is_valid():
form = form.save()
form.create()
return HttpResponseRedirect('/blog')
else:
return HttpResponseRedirect('/blog')
else:
form = BlogForm()
return render(request, 'add_blog.html', {'form': form})
@login_required
def view_blog(request, blog_id):
b,_ = have_I_right(request, blog_id)
posts = Post.objects.filter(blog=b)
count = posts.count()
nb_pages = int(count/50)
if 'page' in request.GET:
cur_page = int(request.GET['page'])
else:
if 'cur_page' in request.session:
cur_page = request.session['cur_page']
else:
cur_page = 0
# Prevent error injection
if cur_page < 0 : cur_page = 0
if cur_page > nb_pages : cur_page = nb_pages-1
request.session['cur_page'] = cur_page
start = cur_page * 50
end = start + 50
posts = posts.order_by('-creation_date')[start:end]
form = BlogForm(instance=b)
comments = Comment.objects.all()
dict_comments = {}
for comment in comments:
key = comment.post.id
if not key in dict_comments:
dict_comments[key] = 1
else:
dict_comments[key] = dict_comments[key] + 1
navigation_bar = createNavigationBar(b.id, cur_page, nb_pages)
c = {'blog' : b, 'posts' : posts, 'form' : form, 'comments' : dict_comments, 'navigation_bar' : navigation_bar}
return render(request, 'templates/view_blog.html', c)
@login_required
def edit_blog(request, blog_id):
if not request.user.is_superuser:
return HttpResponseRedirect('/blog/' + str(blog_id))
b = Blog.objects.get(pk=blog_id)
if b is None:
raise Http404
edited = False
if request.method == 'POST':
if 'edit' in request.POST:
form = BlogForm(request.POST, instance=b)
if form.is_valid():
form.save()
edited = True
else:
if 'delete' in request.POST:
b = Blog.objects.get(pk=blog_id)
b.delete()
return HttpResponseRedirect('/blog')
else:
form = BlogForm(instance=b)
posts = Post.objects.filter(blog=b).order_by('-creation_date')
c = {'blog' : b, 'posts' : posts, 'form' : form, 'edited' : edited}
return render(request, 'templates/view_blog.html', c)
@login_required
def add_post(request, blog_id):
(b,_) = have_I_right(request, blog_id)
if request.method == 'POST':
if 'add' in request.POST:
post = Post(blog=Blog.objects.get(pk=blog_id), author=User.objects.get(pk=request.user.id), creation_date=datetime.now(), modification_date=datetime.now())
content = request.POST['content']
# del request.POST['content']
form = PostForm(request.POST, instance=post)
if form.is_valid():
form = form.save()
form.createPost(content, request.POST['text_tags'])
s = Search()
s.index_post(b, form.id)
return HttpResponseRedirect('/blog/' + blog_id)
else:
return HttpResponseRedirect('/blog/' + blog_id)
else:
form = PostForm()
return render(request, 'add_post.html', {'form': form, 'blog_id' : blog_id})
@login_required
def edit_post(request, post_id):
(b, post) = have_I_right(request, None, post_id)
title = post.title
blog_id = b.id
if request.method == 'POST':
if 'edit' in request.POST:
form = PostForm(request.POST, instance=post)
if form.is_valid():
if title != request.POST['title']:
post.remove()
form.save()
post.createPost(request.POST['content'], request.POST['text_tags'])
s = Search()
s.edit_post(b, post_id)
return HttpResponseRedirect('/blog/' + str(blog_id))
else:
if 'cancel' in request.POST:
return HttpResponseRedirect('/blog/' + str(blog_id))
else:
form = PostForm(instance=post, initial={'text_tags':', '.join((tag.name) for tag in post.tags.all())})
filename = b.src_path + '/_post/' + str(post.pk)
if os.path.exists(filename):
f = open(filename, 'rb')
content = f.read()
f.close()
else:
content = 'Empty post'
comments = Comment.objects.filter(post=post).order_by('date')
comment_list = []
for comment in comments:
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
})
@login_required
def delete_post(request, post_id):
(b, post) = have_I_right(request, None, post_id)
s = Search()
s.delete_post(b, post_id)
post.delete()
return HttpResponseRedirect('/blog/' + str(b.id))
def _generate(request, blog_id, report):
b,_ = have_I_right(request, blog_id)
posts = Post.objects.filter(blog=b).order_by('-creation_date')
nb_pages = int(posts.count()/50)
posts = posts[0:50]
b = Blog.objects.get(pk=blog_id)
form = BlogForm(instance=b)
comments = Comment.objects.all()
dict_comments = {}
for comment in comments:
key = comment.post.id
if not key in dict_comments:
dict_comments[key] = 1
else:
dict_comments[key] = dict_comments[key] + 1
navigation_bar = createNavigationBar(b.id, 0, nb_pages)
c = {'blog' : b, 'posts' : posts, 'form' : form, 'report': report, 'comments' : dict_comments, 'navigation_bar' : navigation_bar}
return render(request, 'templates/generate.html', c)
@login_required
def generate(request, blog_id):
b,_ = have_I_right(request, blog_id)
report = b.generate()
return _generate(request, blog_id, report)
@login_required
def generate_search(request, blog_id):
b,_ = have_I_right(request, blog_id)
hash_posts = {}
hash_posts_content = {}
s = Search(hash_posts, hash_posts_content)
report = s.create_index(b)
return _generate(request, blog_id, report)
@csrf_exempt
def search(request, blog_id):
from dynastie.generators import search
ref = request.META['HTTP_REFERER']
b = Blog.objects.filter(pk=blog_id)
if len(b) == 0:
return HttpResponseRedirect(ref)
b = b[0]
if 'text' in request.POST:
text = request.POST['text']
else:
return HttpResponseRedirect(ref)
s = Search()
post_list = s.search(b, text)
if post_list is None: post_list = []
hash_posts = {}
hash_posts_content = {}
s = search.Search(hash_posts, hash_posts_content)
res = s.generate(b, b.src_path, b.output_path, post_list)
c = {'result' : res}
# Simple wrapper to HTML content
return render(request, 'templates/search.html', c)
@login_required
def preview(request, blog_id):
from dynastie.generators import post
(b, p) = have_I_right(request, blog_id)
values = {'title' : request.POST['title'], \
'author' : request.user.first_name + ' ' + request.user.last_name, \
'content' : request.POST['content']
}
engine = globals()['post']
for name, obj in inspect.getmembers(engine):
if inspect.isclass(obj) and obj.__module__.startswith("dynastie.generators") \
and obj.__module__.endswith("post"):
e = obj()
content = e.preview(b.src_path, values)
break
output = b.output_path
path = output + '/preview.html'
if os.path.exists(path):
os.unlink(path)
f = open(path, 'wb')
f.write(content)
f.close()
c = {'content' : content}
return HttpResponseRedirect('http://' + b.name + '/preview.html')
# return HttpResponseRedirect('http://' + 'localhost:8080' + '/preview.html')
def _tinymcelist(request, b, year, month):
ret = 'var tinyMCEImageList = new Array('
if month < 10:
suffix = '/images/' + str(year) + '/0' + str(month)
else:
suffix = '/images/' + str(year) + '/' + str(month)
path = b.src_path + '/' + suffix
url = 'http://' + b.name + suffix + '/'
if os.path.exists(path):
files = ''
for p in os.listdir(path):
files += '["' + p + '", "' + url + p + '"],'
# Remove last comma
if len(files) != 0:
ret += files[:-1]
ret += ');'
return ret
@login_required
def tinymcelist_add(request, blog_id):
now = datetime.now()
year = now.year
month = now.month
try:
(b, p) = have_I_right(request, blog_id)
except Http404:
return HttpResponse('', content_type='application/x-javascript')
ret = _tinymcelist(request, b, year, month)
return HttpResponse(ret, content_type='application/x-javascript')
@login_required
def tinymcelist_edit(request, post_id):
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)
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']
# Anti robot !!
if request.POST['email'] != '':
print 'fucking robot'
return HttpResponseRedirect(ref)
post = Post.objects.get(pk=post_id)
if post is None:
return HttpResponseRedirect(ref)
blog = Blog.objects.get(pk=post.blog_id)
if blog is None:
return HttpResponseRedirect(ref)
parent_id = int(parent_id)
if parent_id != 0:
parentComment = Comment.objects.get(pk=parent_id)
else:
parentComment = None
if request.POST['author'] == '' or request.POST['the_comment'] == '':
return HttpResponseRedirect(ref)
# Behind nginx proxy
if 'HTTP_X_FORWARDED_FOR' in request.META:
ip = request.META['HTTP_X_FORWARDED_FOR']
else:
ip = request.META['REMOTE_ADDR']
# Avoid script injection
the_comment = request.POST['the_comment']
the_comment = the_comment.replace('<', '&lt;')
the_comment = the_comment.replace('>', '&gt;')
if 'mel' in request.POST:
mel = request.POST['mel'].strip()
else:
mel = ''
comment = Comment(post=post, parent=parentComment, date=datetime.now(), author=request.POST['author'].strip(),\
email=mel, the_comment=the_comment, ip=ip)
comment.save()
engine = globals()['post']
post_list = [post]
hash_post = {}
hash_post_content = {}
for name, obj in inspect.getmembers(engine):
if inspect.isclass(obj) and obj.__module__.startswith("dynastie.generators") \
and obj.__module__.endswith("post"):
e = obj(hash_post, hash_post_content)
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 email != request.POST['mel'] and not email in emails:
emails[email] = comment.author
if post.author.email not in emails:
emails[post.author.email] = post.author.first_name
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 += the_comment
text_body += '\n'
html_body = u'<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8" /></head><body>'
html_body += u'Bonjour %s,<br/><br/>Un nouveau commentaire a été posté pour l\'article "%s".<br/><br/>' % (author, post.title)
html_body = html_body + u'Pour le consulter, rendez vous sur <a href="http://%s%s#comment_%s">http://%s%s#comment_%s</a><br/><br/>----------------<br/><pre>' % (blog.name, post.getPath(), comment_index, blog.name, post.getPath(), comment_index)
c = comment.the_comment
html_body += the_comment + '</pre>'
html_body += '</body></html>'
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['Cache-Control'] = 'no-store, no-cache, must-revalidate'
response['Expires'] = 'Thu, 01 Jan 1970 00:00:00 GMT'
response.set_cookie('author', request.POST['author'], domain=blog.name, secure=True, httponly=False);
if mel != '':
response.set_cookie('email', mel, domain=blog.name, secure=True, httponly=False);
return response
@login_required
def edit_comment(request, 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 = comment.post_id
if request.method == 'POST':
if 'edit' in request.POST:
form = CommentForm(request.POST, instance=comment)
if form.is_valid():
form = form.save()
return HttpResponseRedirect('/post/edit/' + str(post_id))
else:
return HttpResponseRedirect('/post/edit/' + str(post_id))
else:
form = CommentForm(instance=comment)
return render(request, 'edit_comment.html', {'form': form, 'comment':comment})
@login_required
def delete_comment(request, 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 = comment.post_id
childs = Comment.objects.filter(parent=comment.id)
try:
parent = comment.parent
except:
parent = None
for child in childs:
child.parent = parent
child.save()
comment.delete()
return HttpResponseRedirect('/post/edit/' + str(post_id))