diff --git a/ChangeLog b/ChangeLog
index cd3e5fc..1a5174a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+v0.3 (27/05/2014)
+** User **
+ Add draft support
+
+** Dev **
+
+** Bugs **
+
+
v0.2 (27/04/2014)
** User **
diff --git a/dynastie/forms.py b/dynastie/forms.py
index 0860bdb..9cdd355 100755
--- a/dynastie/forms.py
+++ b/dynastie/forms.py
@@ -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
diff --git a/dynastie/models.py b/dynastie/models.py
index cc637cb..5d7d5b4 100755
--- a/dynastie/models.py
+++ b/dynastie/models.py
@@ -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)
diff --git a/dynastie/sites/blog.soutade.fr/_base.html b/dynastie/sites/blog.soutade.fr/_base.html
index e7a5b82..fc768b5 100755
--- a/dynastie/sites/blog.soutade.fr/_base.html
+++ b/dynastie/sites/blog.soutade.fr/_base.html
@@ -14,7 +14,7 @@
-
+
diff --git a/dynastie/sites/blog.soutade.fr/_base_post.html b/dynastie/sites/blog.soutade.fr/_base_post.html
index 2cb4abc..e262102 100644
--- a/dynastie/sites/blog.soutade.fr/_base_post.html
+++ b/dynastie/sites/blog.soutade.fr/_base_post.html
@@ -15,7 +15,7 @@
-
+
diff --git a/dynastie/sites/blog.soutade.fr/_ljdc.xml b/dynastie/sites/blog.soutade.fr/_ljdc.xml
index c704657..699dad3 100644
--- a/dynastie/sites/blog.soutade.fr/_ljdc.xml
+++ b/dynastie/sites/blog.soutade.fr/_ljdc.xml
@@ -1,5 +1,23 @@
+
+ 85704348740
+ http://lesjoiesducode.fr/post/85704348740/quand-le-client-reclame-une-feature-hors-cahier-des
+ quand le client réclame une feature hors cahier des charges et qu'on lui renvoie en réponse sa facture impayée
+ http://i.imgur.com/3minh1d.gif
+
+
+ 72755714066
+ http://lesjoiesducode.fr/post/72755714066/quand-on-me-demande-si-je-veux-relire-la-doc
+ quand on me demande si je veux relire la doc
+ http://ljdchost.com/5jFD7OS.gif
+
+
+ 84217503221
+ http://thecodinglove.com/post/84217503221/when-i-have-a-bad-feeling-about-the-project
+ when I have a bad feeling about the project
+ http://i.imgur.com/GMU8de2.gif
+
84208887361
http://thecodinglove.com/post/84208887361/when-the-intern-modifies-my-code
@@ -160,7 +178,7 @@
69485497531
http://lesjoiesducode.fr/post/69485497531/quand-les-collegues-se-ramassent-sur-un-projet-sur
quand les collègues se ramassent sur un projet sur lequel je ne travaille pas
- http://i.imgur.com/4YwDi.png
+ http://ljdchost.com/FCpwSIk.gif
68966745060
diff --git a/dynastie/templates/add_post.html b/dynastie/templates/add_post.html
index a9321b8..6cf271b 100755
--- a/dynastie/templates/add_post.html
+++ b/dynastie/templates/add_post.html
@@ -32,7 +32,7 @@ Available tags:
{% endif %}
-
+
{% if editor == "html" %}
diff --git a/dynastie/templates/view_blog.html b/dynastie/templates/view_blog.html
index 4079ee7..84f1e2b 100755
--- a/dynastie/templates/view_blog.html
+++ b/dynastie/templates/view_blog.html
@@ -19,10 +19,20 @@
{% csrf_token %}
+{% if drafts|length != 0 %}
+
Drafts
+
+{% for draft in drafts %}
+ {{ draft.id }} {{ draft.title }} {{ draft.creation_date }} {{ draft.modification_date }} Delete
+{% endfor %}
+
+{% endif %}
+
{% if posts|length == 0 %}
Any post available
{% else %}
+
Posts
{% for post in posts %}
{% with post.id as cur_id %}
diff --git a/dynastie/urls.py b/dynastie/urls.py
index 101f9d8..d70ec25 100755
--- a/dynastie/urls.py
+++ b/dynastie/urls.py
@@ -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'),
diff --git a/dynastie/views.py b/dynastie/views.py
index 28843cb..d52d5a5 100755
--- a/dynastie/views.py
+++ b/dynastie/views.py
@@ -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)