import os import datetime import xml from xml.parsers.expat import * from xml.dom.minidom import parse, parseString from dynastie.generators.generator import DynastieGenerator, StrictUTF8Writer from django.db import models class Index(DynastieGenerator): cur_page = 0 nb_pages = 0 cur_post = 0 cur_post_obj = None posts_per_page = 0 filename = 'index' dirname = '' blog = None def __init__(self, hash_posts=None, hash_posts_content=None): DynastieGenerator.__init__(self, hash_posts, hash_posts_content) self.hooks = {'posts' : self.createPosts, 'title' : self.createTitle, 'navigation' : self.createNavigation, 'recents' : self.createRecents, 'tags' : self.createTags, 'replace' : self.createReplace} self.first_try = True def createReplace(self, posts, 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:blog_id', str(self.blog.id)) div_element.setAttribute(key, value) root.replaceChild(div_element, replace_elem) return div_element def createNavigation(self, posts, dom, root, node): if self.nb_pages == 0 or self.nb_pages == 1: return None if self.dirname != '': if self.dirname.startswith('/'): href = '<< First ' if self.cur_page == 1: nav = nav + href + '.html">< Prev ' else: nav = nav + href + str(self.cur_page-1) + '.html">< Prev ' start = self.cur_page-5 if start < 0: start = 0 end = start + 10 if end > self.nb_pages: end = self.nb_pages for i in range(start, end): if i == self.cur_page: nav = nav + str(i+1) + ' ' else: if i == 0: nav = nav + href + '.html">1 ' else: nav = nav + href + str(i) + '.html">' + str(i+1) + ' ' if self.cur_page < self.nb_pages-1: nav = nav + href + str(self.cur_page+1) + '.html">Next > ' nav = nav + href + str(self.nb_pages-1) + '.html">Last >>' new_dom = parseString('
') new_node = new_dom.getElementsByTagName('div')[0] res = new_node.cloneNode(True) root.replaceChild(res, node) return res def createTitle(self, posts, dom, root, title_elem): create_link = (title_elem.getAttribute('link') == '1') post = self.cur_post_obj if create_link == True: node = self.createElement(dom, 'title') node.appendChild(self.createLinkElem(dom, post.getPath(), post.title)) else: node = self.createElement(dom, 'title', post.title) root.replaceChild(node, title_elem) def createPost(self, posts, dom, post_elem, root): post = self.cur_post_obj if post.id in self.hash_posts and not self.first_try: node = self.hash_posts[post.id] return node.cloneNode(0) values = {} values['author'] = post.author.first_name + ' ' + post.author.last_name values['date'] = post.creation_date.strftime('%A, %d %B %Y %H:%m') values['post_content'] = '' blog = post.blog blog.create_paths() filename = blog.src_path + '/_post/' + str(post.id) if not os.path.exists(filename): self.addError('File does not exists ' + filename) return None if not filename in self.hash_posts_content: f = open(filename, 'rb') post_content = f.read() f.close() self.hash_posts_content[filename] = post_content else: post_content = self.hash_posts_content[filename] while True: start = post_content.find('aftercode = code[28:-13] code = '' + code + '' return code def parseTemplate(self, blog, src, output, name, directory=None): self.blog = blog if not os.path.exists(src + '/_%s.html' % name): self.addError('No _%s.html found, exiting' % name) return None try: dom = parse(src + '/_%s.html' % name) except xml.dom.DOMException as e: self.addError('Error parsing _%s.html : ' + e) return None if not directory is None and not os.path.exists(output + '/' + directory): os.mkdir(output + '/' + directory) post_nodes = dom.getElementsByTagNameNS(self.URI, "posts") if not post_nodes is None: if post_nodes[0].hasAttribute("limit"): self.posts_per_page = int(post_nodes[0].getAttribute("limit")) else: self.posts_per_page = 5 else: self.addError('No tag dyn:posts found') return dom def generatePages(self, dom, posts, src, output, name, directory=None): if len(posts) > self.posts_per_page: self.nb_pages = self.computeNbPages(len(posts), self.posts_per_page) if not directory is None and not os.path.exists(output + self.dirname): os.mkdir(output + self.dirname) filename = self.dirname + '/' + self.filename + '.html' impl = xml.dom.getDOMImplementation() while self.cur_page <= self.nb_pages: #print 'Generate ' + filename dom_ = impl.createDocument('', 'xml', None) dom_.replaceChild(dom.firstChild.cloneNode(0), dom_.firstChild) nodes = dom.getElementsByTagName("*") 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 = self.dirname + '/' + self.filename + str(self.cur_page) + '.html' filename = output + filename while os.path.exists(filename): self.addReport('Removing unused ' + filename) os.unlink(filename) filename = filename + '.gz' if os.path.exists(filename): self.addReport('Removing unused ' + filename) os.unlink(filename) self.cur_page = self.cur_page + 1 filename = self.dirname + '/' + self.filename + str(self.cur_page) + '.html' filename = output + filename def generate(self, blog, src, output): from dynastie.models import Post, Blog dom = self.parseTemplate(blog, src, output, 'index') if dom is None: return self.report now = datetime.datetime.now() cur_year = now.year posts = Post.objects.filter(creation_date__year=cur_year, published=True, front_page=True).order_by('-creation_date') if posts.count() < self.posts_per_page: posts = Post.objects.filter(published=True, front_page=True).order_by('-creation_date')[:self.posts_per_page] self.dirname = '' self.generatePages(dom, posts, src, output, 'index') if not self.somethingWrote: self.addReport('Nothing changed') return self.report