diff --git a/forms.py b/forms.py index 51faa40..21c3d5e 100644 --- a/forms.py +++ b/forms.py @@ -1,4 +1,5 @@ from django.forms import ModelForm +from django import forms from dynastie.models import * class BlogForm(ModelForm): @@ -6,6 +7,10 @@ class BlogForm(ModelForm): model = Blog class PostForm(ModelForm): + description = forms.CharField(widget=forms.Textarea(attrs={'rows':'5', 'cols':'50'}), required=False) + keywords = forms.CharField(widget=forms.Textarea(attrs={'rows':'2', 'cols':'50'}), required=False) + text_tags = forms.CharField(widget=forms.Textarea(attrs={'rows':'2', 'cols':'50'}), required=False) + class Meta: model = Post exclude = ('title_slug', 'creation_date', 'modification_date', 'author', 'blog', 'tags') @@ -28,3 +33,8 @@ class CommentForm(ModelForm): class Meta: model = Comment exclude = ('post', 'parent', 'date') + +class TagForm(ModelForm): + class Meta: + model = Tag + exclude = ('blog', 'name_slug') diff --git a/generators/__init__.py b/generators/__init__.py index bd07e83..db72da4 100644 --- a/generators/__init__.py +++ b/generators/__init__.py @@ -1 +1 @@ -__all__ = ["generator", "index", "post", "category", "archive", "rss", "atom"] +__all__ = ["generator", "index", "post", "category", "tag", "archive", "rss", "atom"] diff --git a/generators/archive.py b/generators/archive.py index 0ffae95..808430f 100644 --- a/generators/archive.py +++ b/generators/archive.py @@ -57,9 +57,10 @@ class Archive(Index): def generate(self, blog, src, output): from dynastie.models import Post, Blog - hooks = {'posts' : self.createPosts, + self.hooks = {'posts' : self.createPosts, 'navigation' : self.createNavigation, - 'archive' : self.createArchive} + 'archive' : self.createArchive, + 'tags' : self.createTags} if not os.path.exists(src + '/_archive.html'): self.addError('No _archive.html found, exiting') @@ -99,7 +100,7 @@ class Archive(Index): if posts[i].creation_date.year != posts[i+1].creation_date.year: dom = parse(src + '/_archive.html') my_post.reverse() - self.createArchives(src, output, dom, hooks, my_post) + self.createArchives(src, output, dom, self.hooks, my_post) self.cur_year = int(posts[i+1].creation_date.year) #print 'New year ' + str(self.cur_year) my_post = [] @@ -114,7 +115,7 @@ class Archive(Index): self.cur_year = int(posts[i].creation_date.year) if len(my_post) != 0: - self.createArchives(src, output, dom, hooks, my_post) + self.createArchives(src, output, dom, self.hooks, my_post) if not self.somethingWrote: self.addReport('Nothing changed') diff --git a/generators/category.py b/generators/category.py index 3c3aff2..28a2f1a 100644 --- a/generators/category.py +++ b/generators/category.py @@ -24,9 +24,10 @@ class Category(Index): def generate(self, blog, src, output): from dynastie.models import Post, Blog, Category - hooks = {'posts' : self.createPosts, + self.hooks = {'posts' : self.createPosts, 'navigation' : self.createNavigation, - 'category' : self.createCategory} + 'category' : self.createCategory, + 'tags' : self.createTags} if not os.path.exists(src + '/_category.html'): self.addError('No _category.html found, exiting') @@ -73,7 +74,7 @@ class Category(Index): while self.cur_page <= self.nb_pages: #print 'Generate ' + filename nodes = dom.getElementsByTagName("*") - nodes[0] = self.parse(src, hooks, posts, dom, nodes[0]) + nodes[0] = self.parse(src, self.hooks, posts, dom, nodes[0]) self.writeIfNotTheSame(output + self.dirname + '/' + filename, nodes[0]) self.cur_page = self.cur_page + 1 filename = self.filename + str(self.cur_page) + '.html' diff --git a/generators/index.py b/generators/index.py index ccdfac1..e74700f 100644 --- a/generators/index.py +++ b/generators/index.py @@ -105,6 +105,9 @@ class Index(DynastieGenerator): post_elem = self.createElement(dom, '', 'No posts yet') posts_elem.appendChild(post_elem) + # Parse inner HTML + self._parse(self.hooks, posts, dom, post_elem) + self.cur_post = self.cur_post + 1 if self.cur_post == len(posts): break @@ -139,12 +142,48 @@ class Index(DynastieGenerator): return recents_elem + def createTags(self, posts, dom, root, node): + from dynastie.models import Post + tags_elem = self.createElement(dom, 'tags') + create_link = (node.getAttribute('link') == '1') + if type(posts) == models.query.QuerySet: + if len(posts) > self.cur_post: + cur_post = posts[self.cur_post] + else: + cur_post = None + elif type(posts) == Post: + cur_post = posts + else: + cur_post = None + + if not cur_post is None: + for tag in cur_post.tags.all(): + if create_link: + tag_elem = self.createElement(dom, 'tag') + link_elem = self.createLinkElem(dom, '/tag/' + tag.name_slug, '#' + tag.name) + tag_elem.appendChild(link_elem) + else: + tag_elem = self.createElement(dom, 'tag', '#' + tag.name) + tags_elem.appendChild(tag_elem) + + if len(cur_post.tags.all()) == 0: + root.removeChild(node) + return None + else: + root.replaceChild(tags_elem, node) + else: + root.removeChild(node) + return None + + return tags_elem + def generate(self, blog, src, output): from dynastie.models import Post, Blog - hooks = {'posts' : self.createPosts, + self.hooks = {'posts' : self.createPosts, 'navigation' : self.createNavigation, - 'recents' : self.createRecents} + 'recents' : self.createRecents, + 'tags' : self.createTags} if not os.path.exists(src + '/_index.html'): self.addError('No _index.html found, exiting') @@ -180,7 +219,7 @@ class Index(DynastieGenerator): while self.cur_page <= self.nb_pages: #print 'Generate ' + filename nodes = dom.getElementsByTagName("*") - nodes[0] = self.parse(src, hooks, posts, dom, nodes[0]) + nodes[0] = self.parse(src, self.hooks, posts, dom, nodes[0]) self.writeIfNotTheSame(output + '/' + filename, nodes[0]) self.cur_page = self.cur_page + 1 filename = 'index' + str(self.cur_page) + '.html' diff --git a/generators/post.py b/generators/post.py index 5d39d79..54102c6 100644 --- a/generators/post.py +++ b/generators/post.py @@ -138,9 +138,10 @@ class Post(Index): def _generate(self, blog, src, output, posts): import xml self.hooks = {'post' : self._createPost, - 'meta' : self.createMetas, - 'comments' : self.createComments, - 'replace' : self.createReplace} + 'meta' : self.createMetas, + 'comments' : self.createComments, + 'replace' : self.createReplace, + 'tags' : self.createTags} if not os.path.exists(src + '/_post.html'): self.addError('No _post.html found, exiting') @@ -210,7 +211,8 @@ class Post(Index): def preview(self, src, values): from dynastie.models import Blog - self.hooks = {'post' : self.createPreview} + self.hooks = {'post' : self.createPreview, + 'tags' : self.createTags} if not os.path.exists(src + '/_post.html'): self.addError('No _post.html found, exiting') diff --git a/models.py b/models.py index 6e067c1..4e6cdd0 100644 --- a/models.py +++ b/models.py @@ -12,6 +12,15 @@ from django.db.models.signals import post_init, post_delete, post_save from django.dispatch import receiver from dynastie.generators import * +def slugify(name): + name = name.strip() + name = normalize('NFKD', name).encode('ascii', 'ignore').replace(' ', '-').lower() + #remove `other` characters + name = sub('[^a-zA-Z0-9_-]', '', name) + #nomalize dashes + name = sub('-+', '-', name) + return name + class Blog(models.Model): name = models.CharField(max_length=255, unique=True) title = models.CharField(max_length=255) @@ -61,7 +70,10 @@ class Blog(models.Model): self.engines.append(globals()['post']) self.engines.append(globals()['index']) self.engines.append(globals()['category']) + self.engines.append(globals()['tag']) self.engines.append(globals()['archive']) + self.engines.append(globals()['atom']) + self.engines.append(globals()['rss']) def copytree(self, src, dst): names = os.listdir(src) @@ -161,29 +173,34 @@ class Category(models.Model): 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() - #remove `other` characters - name = sub('[^a-zA-Z0-9_-]', '', name) - #nomalize dashes - name = sub('-+', '-', name) - self.name_slug = name - def save(self): - self.slugify() + self.name_slug = slugify(self.name) super(Category, self).save() def remove(self, blog): blog.create_paths() output = blog.output_path + '/category/' + self.name_slug - shutil.rmtree(output) + if os.path.exists(output): + shutil.rmtree(output) class Tag(models.Model): name = models.CharField(max_length=255, unique=True) + name_slug = models.CharField(max_length=255) blog = models.ForeignKey(Blog) + def save(self): + self.name_slug = slugify(self.name) + super(Tag, self).save() + + def remove(self, blog): + blog.create_paths() + + output = blog.output_path + '/tag/' + self.name_slug + if os.path.exists(output): + shutil.rmtree(output) + class Post(models.Model): title = models.CharField(max_length=255) title_slug = models.CharField(max_length=255) @@ -204,19 +221,12 @@ class Post(models.Model): filename = filename + self.title_slug + '.html' return filename - def slugify(self): - name = normalize('NFKD', self.title).encode('ascii', 'ignore').replace(' ', '-').lower() - #remove `other` characters - name = sub('[^a-zA-Z0-9_-]', '', name) - #nomalize dashes - name = sub('-+', '-', name) - self.title_slug = name - def save(self): - self.slugify() + self.title = self.title.strip() + self.title_slug = slugify(self.title) super(Post, self).save() - def createPost(self, content): + def createPost(self, content, tags): b = self.blog b.create_paths() output = b.src_path @@ -224,12 +234,75 @@ class Post(models.Model): os.mkdir(output + '/_post') filename = output + '/_post/' + str(self.pk) - if os.path.exists(filename): - os.unlink(filename) - f = open(filename, 'wb') content = unicode(content) - f.write(content.encode('utf-8')) - f.close() + 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() + + tags_list = Tag.objects.filter(blog_id=self.blog.id) + my_tags = [] + # Create new tags + for tag in tags.split(','): + tag_slug = slugify(tag) + found = False + for t in tags_list: + if t.name_slug == tag_slug: + found = True + break + if not found and not tag in my_tags: + t = Tag(blog=self.blog, name=tag.strip(), name_slug=tag_slug) + t.save() + # print 'Create ' + tag_slug + my_tags.append(tag) + + # Add new tags + post_tags_list = Tag.objects.filter(post=self.id) + for tag in tags.split(','): + tag_slug = slugify(tag) + found = False + for t in post_tags_list: + if t.name_slug == tag_slug: + found = True + break + if not found: + for t in tags_list: + if t.name_slug == tag_slug: + self.tags.add(t) + # print 'Add ' + tag_slug + break + + # Remove old tags + for t in post_tags_list: + found = False + for tag in tags.split(','): + tag_slug = slugify(tag) + if t.name_slug == tag_slug: + found = True + break + if not found: + # print 'Remove ' + t.name_slug + self.tags.remove(t) + + self.save() def remove(self): b = self.blog @@ -267,7 +340,7 @@ class Comment(models.Model): ip = models.GenericIPAddressField() @receiver(post_init, sender=Blog) -def delete_blog_signal(sender, **kwargs): +def init_blog_signal(sender, **kwargs): kwargs['instance'].create_paths() @receiver(post_delete, sender=Blog) diff --git a/sites/blog.soutade.fr/_archive.html b/sites/blog.soutade.fr/_archive.html index 5ca1e8d..ef6a34f 100755 --- a/sites/blog.soutade.fr/_archive.html +++ b/sites/blog.soutade.fr/_archive.html @@ -6,6 +6,7 @@