Add Draft support

This commit is contained in:
Gregory Soutade 2014-05-27 18:24:14 +02:00
parent c468ea92b0
commit 03f646b7fa
10 changed files with 232 additions and 43 deletions

View File

@ -1,3 +1,12 @@
v0.3 (27/05/2014)
** User **
Add draft support
** Dev **
** Bugs **
v0.2 (27/04/2014)
** User **

View File

@ -38,6 +38,11 @@ class PostForm(ModelForm):
super(PostForm, self).__init__(*args, **kwargs)
self.fields['category'].choices = [(cat.id, cat.name) for cat in Category.objects.all()]
class DraftForm(PostForm):
class Meta:
model = Draft
exclude = ('title_slug', 'creation_date', 'modification_date', 'author', 'blog', 'tags', 'content_format', 'published')
class CategoryForm(ModelForm):
class Meta:
model = Category

View File

@ -253,37 +253,7 @@ class Post(models.Model):
self.title_slug = slugify(self.title)
super(Post, self).save()
def createPost(self, content, tags):
b = self.blog
output = b.src_path
if not os.path.exists(output + '/_post'):
os.mkdir(output + '/_post')
filename = output + '/_post/' + str(self.pk)
content = unicode(content)
content = content.encode('utf-8')
modif = True
if os.path.exists(filename):
f = open(filename, 'rb')
src_md5 = hashlib.md5()
src_md5.update(f.read())
f.close()
dst_md5 = hashlib.md5()
dst_md5.update(content)
if src_md5.digest() == dst_md5.digest():
modif = False
else:
os.unlink(filename)
if modif:
f = open(filename, 'wb')
f.write(content)
f.close()
self.modification_date=datetime.now()
def manageTags(self, tags):
tags_list = Tag.objects.filter(blog_id=self.blog.id)
my_tags = []
# Create new tags
@ -334,6 +304,38 @@ class Post(models.Model):
# print 'Remove ' + t.name_slug
self.tags.remove(t)
def createPost(self, content, tags):
b = self.blog
output = b.src_path
if not os.path.exists(output + '/_post'):
os.mkdir(output + '/_post')
filename = output + '/_post/' + str(self.pk)
content = unicode(content)
content = content.encode('utf-8')
modif = True
if os.path.exists(filename):
f = open(filename, 'rb')
src_md5 = hashlib.md5()
src_md5.update(f.read())
f.close()
dst_md5 = hashlib.md5()
dst_md5.update(content)
if src_md5.digest() == dst_md5.digest():
modif = False
else:
os.unlink(filename)
if modif:
f = open(filename, 'wb')
f.write(content)
f.close()
self.modification_date=datetime.now()
self.manageTags(tags)
self.save()
def remove(self):
@ -368,6 +370,53 @@ class Post(models.Model):
else:
return 'text'
class Draft(Post):
def createDraft(self, content, tags):
b = self.blog
output = b.src_path
if not os.path.exists(output + '/_draft'):
os.mkdir(output + '/_draft')
filename = output + '/_draft/' + str(self.pk)
content = unicode(content)
content = content.encode('utf-8')
modif = True
if os.path.exists(filename):
f = open(filename, 'rb')
src_md5 = hashlib.md5()
src_md5.update(f.read())
f.close()
dst_md5 = hashlib.md5()
dst_md5.update(content)
if src_md5.digest() == dst_md5.digest():
modif = False
else:
os.unlink(filename)
if modif:
f = open(filename, 'wb')
f.write(content)
f.close()
self.modification_date=datetime.now()
self.manageTags(tags)
self.save()
def remove(self):
b = self.blog
output = b.src_path
filename = output + '/_draft/' + str(self.pk)
if os.path.exists(filename):
os.unlink(filename)
def save(self):
self.published = False
super(Draft, self).save()
class Comment(models.Model):
post = models.ForeignKey(Post)
parent = models.ForeignKey('self', null=True, blank=True)

View File

@ -14,7 +14,7 @@
<dyn:block name="head"/>
</head>
<body>
<img id="logo" src="/images/tux_final.png"/>
<a href="/"><img id="logo" src="/images/tux_final.png"/></a>
<div class="body">
<div class="table-row">
<header>

View File

@ -15,7 +15,7 @@
<script type="text/javascript" src="/js/blog.js"> </script>
</head>
<body onLoad="javascript:init();">
<img id="logo" src="/images/tux_final.png"/>
<a href="/"><img id="logo" src="/images/tux_final.png"/></a>
<div class="body">
<div class="table-row">
<header>

View File

@ -1,5 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<ljdc>
<entry>
<id>85704348740</id>
<address>http://lesjoiesducode.fr/post/85704348740/quand-le-client-reclame-une-feature-hors-cahier-des</address>
<title>quand le client réclame une feature hors cahier des charges et qu'on lui renvoie en réponse sa facture impayée</title>
<img>http://i.imgur.com/3minh1d.gif</img>
</entry>
<entry>
<id>72755714066</id>
<address>http://lesjoiesducode.fr/post/72755714066/quand-on-me-demande-si-je-veux-relire-la-doc</address>
<title>quand on me demande si je veux relire la doc</title>
<img>http://ljdchost.com/5jFD7OS.gif</img>
</entry>
<entry>
<id>84217503221</id>
<address>http://thecodinglove.com/post/84217503221/when-i-have-a-bad-feeling-about-the-project</address>
<title>when I have a bad feeling about the project</title>
<img>http://i.imgur.com/GMU8de2.gif</img>
</entry>
<entry>
<id>84208887361</id>
<address>http://thecodinglove.com/post/84208887361/when-the-intern-modifies-my-code</address>
@ -160,7 +178,7 @@
<id>69485497531</id>
<address>http://lesjoiesducode.fr/post/69485497531/quand-les-collegues-se-ramassent-sur-un-projet-sur</address>
<title>quand les collègues se ramassent sur un projet sur lequel je ne travaille pas</title>
<img>http://i.imgur.com/4YwDi.png</img>
<img>http://ljdchost.com/FCpwSIk.gif</img>
</entry>
<entry>
<id>68966745060</id>

View File

@ -32,7 +32,7 @@ Available tags:
<textarea id="content" name="content" cols="100" rows="25"></textarea>
{% endif %}
<br/>
<input type="submit" name="add" value="Add" /><input type="button" name="preview" value="Preview" onClick="previewPost({{ blog_id }});"/><input type="submit" name="cancel" value="Cancel" />
<input type="submit" name="add" value="Add" /><input type="button" name="preview" value="Preview" onClick="previewPost({{ blog_id }});"/><input type="submit" name="draft" value="Save as draft" /><input type="submit" name="cancel" value="Cancel" />
</form>
{% if editor == "html" %}
<div id="markdown_help" style="display:none">

View File

@ -19,10 +19,20 @@
{% csrf_token %}
<input name="text"/><input type="submit" name="search" value="Search" />
</form>
{% if drafts|length != 0 %}
<b>Drafts</b>
<table>
{% for draft in drafts %}
<tr><td><a href="/draft/edit/{{ draft.id }}">{{ draft.id }}</a></td><td>{{ draft.title }}</td><td>{{ draft.creation_date }}</td><td>{{ draft.modification_date }}</td><td><a href="/draft/delete/{{ draft.id }}" onclick="return confirm('Do you really want to delete this item ?')">Delete</a></td></tr>
{% endfor %}
</table><br/>
{% endif %}
{% if posts|length == 0 %}
<br/><br/>
<b>Any post available</b><br/><br/>
{% else %}
<b>Posts</b>
<table>
{% for post in posts %}
{% with post.id as cur_id %}

View File

@ -44,6 +44,8 @@ urlpatterns = patterns('',
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'^draft/edit/(\d+)$', 'dynastie.views.edit_draft', name='edit_draft'),
url(r'^draft/delete/(\d+)$', 'dynastie.views.delete_draft', name='delete_draft'),
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'),

View File

@ -46,7 +46,7 @@ def hash(object, attr):
value = None
return value
def have_I_right(request, blog_id=None, post_id=None, must_be_superuser=False):
def have_I_right(request, blog_id=None, post_id=None, must_be_superuser=False, cls=Post):
b = None
p = None
@ -54,7 +54,7 @@ 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.get(pk=post_id)
p = cls.objects.get(pk=post_id)
if p is None:
raise Http404
@ -346,9 +346,8 @@ def add_blog(request):
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)
orig_posts = Post.objects.filter(blog=b)
if 'page' in request.GET:
cur_page = int(request.GET['page'])
else:
@ -357,6 +356,14 @@ def view_blog(request, blog_id):
else:
cur_page = 0
if cur_page <= 0:
drafts = Draft.objects.filter(blog=b)
else:
drafts = []
count = orig_posts.count() - drafts.count()
nb_pages = int(count/50)
# Prevent error injection
if cur_page < 0 : cur_page = 0
if cur_page > nb_pages : cur_page = nb_pages-1
@ -364,9 +371,19 @@ def view_blog(request, blog_id):
request.session['cur_page'] = cur_page
start = cur_page * 50
end = start + 50
end = start + 50 + drafts.count()
posts = posts.order_by('-creation_date')[start:end]
orig_posts = orig_posts.order_by('-creation_date')[start:end]
posts = []
for p in orig_posts:
found = False
for d in drafts:
if d.id == p.id:
found = True
break
if not found:
posts.append(p)
form = BlogForm(instance=b)
comments = Comment.objects.all()
@ -380,7 +397,7 @@ def view_blog(request, blog_id):
navigation_bar = createNavigationBar(b.id, cur_page, nb_pages)
c = {'blog' : b, 'posts' : posts, 'form' : form, 'comments' : dict_comments, 'navigation_bar' : navigation_bar}
c = {'blog' : b, 'posts' : posts, 'drafts' : drafts, 'form' : form, 'comments' : dict_comments, 'navigation_bar' : navigation_bar}
return render(request, 'view_blog.html', c)
@ -473,6 +490,20 @@ def add_post(request, blog_id):
s.index_post(b, form.id)
request.session['cur_page'] = 0
return HttpResponseRedirect('/blog/' + blog_id)
elif 'draft' in request.POST:
content_format = Post.CONTENT_HTML
if request.POST['editor'] == 'text':
content_format = Post.CONTENT_TEXT
draft = Draft(blog=Blog.objects.get(pk=blog_id), author=User.objects.get(pk=request.user.id), creation_date=datetime.now(), modification_date=datetime.now(), content_format=content_format, published=False)
content = request.POST['content']
# del request.POST['content']
form = DraftForm(request.POST, instance=draft)
if form.is_valid():
form = form.save()
form.createDraft(content, request.POST['text_tags'])
request.session['cur_page'] = 0
return HttpResponseRedirect('/blog/' + blog_id)
else:
return HttpResponseRedirect('/blog/' + blog_id)
else:
@ -532,6 +563,63 @@ def edit_post(request, post_id):
'editor' : post.get_editor()
})
@login_required
def edit_draft(request, draft_id):
(b, draft) = have_I_right(request, None, draft_id, cls=Draft)
title = draft.title
blog_id = b.id
if request.method == 'POST':
if 'edit' in request.POST:
content_format = Post.CONTENT_HTML
if request.POST['editor'] == 'text':
content_format = Post.CONTENT_TEXT
draft.content_format = content_format
form = DraftForm(request.POST, instance=draft)
if form.is_valid():
if title != request.POST['title']:
draft.remove()
form.save()
draft.createDraft(request.POST['content'], request.POST['text_tags'])
return HttpResponseRedirect('/blog/' + str(blog_id))
elif 'post' in request.POST:
content_format = Post.CONTENT_HTML
if request.POST['editor'] == 'text':
content_format = Post.CONTENT_TEXT
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_format=content_format)
content = request.POST['content']
# del request.POST['content']
form = PostForm(request.POST, instance=post)
if form.is_valid():
draft.delete()
form = form.save()
form.createPost(content, request.POST['text_tags'])
s = Search()
s.index_post(b, form.id)
request.session['cur_page'] = 0
return HttpResponseRedirect('/blog/' + str(blog_id))
else:
if 'cancel' in request.POST:
return HttpResponseRedirect('/blog/' + str(blog_id))
else:
form = PostForm(instance=draft, initial={'text_tags':', '.join((tag.name) for tag in draft.tags.all())})
filename = b.src_path + '/_draft/' + str(draft.pk)
if os.path.exists(filename):
f = open(filename, 'rb')
content = f.read()
f.close()
else:
content = 'Empty draft'
return render(request, 'edit_draft.html', {
'form': form, 'draft_id' : draft_id, 'content' : content,
'blog_id' : blog_id,
'all_tags' : Tag.objects.all(),
'editor' : draft.get_editor()
})
@login_required
def delete_post(request, post_id):
(b, post) = have_I_right(request, None, post_id)
@ -543,6 +631,14 @@ def delete_post(request, post_id):
return HttpResponseRedirect('/blog/' + str(b.id))
@login_required
def delete_draft(request, draft_id):
(b, draft) = have_I_right(request, None, draft_id, cls=Draft)
draft.delete()
return HttpResponseRedirect('/blog/' + str(b.id))
def _generate(request, blog_id, report):
b,_ = have_I_right(request, blog_id)