Add RSS and Atom generators

Compress some static files when copy (and not only when generate)
Fix a visual bug with articles table
This commit is contained in:
Grégory Soutadé 2012-08-25 22:33:34 +02:00
parent a5c5e7edc8
commit e270a52e41
7 changed files with 185 additions and 5 deletions

View File

@ -1 +1 @@
__all__ = ["generator", "index", "article", "category", "archive"] __all__ = ["generator", "index", "article", "category", "archive", "rss", "atom"]

73
generators/atom.py Normal file
View File

@ -0,0 +1,73 @@
import os
import datetime
import xml
from dynastie.generators.generator import DynastieGenerator
from dynastie.generators.rss import RSS
from xml.dom.minidom import getDOMImplementation
from django.db import models
class Atom(RSS):
def generate(self, blog, src, output):
from dynastie.models import Article, Blog
now = datetime.datetime.now()
impl = getDOMImplementation()
dom = impl.createDocument(None, "feed", None)
root = dom.documentElement
root.setAttributeNS('xml', 'xml:lang', 'en-gb')
root.setAttribute('xmlns', 'http://www.w3.org/2005/Atom')
self.appendElement(dom, root, 'title', blog.title, {'type':'text'})
self.appendElement(dom, root, 'subtitle', blog.description, {'type':'text'})
address = 'http://' + blog.name
self.appendElement(dom, root, 'link', '', {'rel':'alternate', 'type':'text/html', 'href' : address})
self.appendElement(dom, root, 'id', address)
builddate = now.strftime('%Y-%m-%dT%H:%M:%SZ')
self.appendElement(dom, root, 'updated', builddate)
self.appendElement(dom, root, 'generator', 'The Dynastie project', {'uri':'http://indefero.soutade.fr/p/dynastie', 'version':'0.1'})
self.appendElement(dom, root, 'link', '', {'rel':'self', 'type':'application/atom+xml', 'href':address + '/atom.xml'})
articles = Article.objects.filter(published=True).order_by('-creation_date')[:10]
for article in articles:
item = dom.createElement('entry')
self.appendElement(dom, item, 'title', article.title)
path = 'http://' + blog.name + article.getPath()
self.appendElement(dom, item, 'link', '', {'rel':'alternate', 'type':'text/html', 'href':path})
creationDate = article.creation_date.strftime('%Y-%m-%dT%H:%M:%SZ')
self.appendElement(dom, item, 'published', creationDate)
self.appendElement(dom, item, 'updated', creationDate)
self.appendElement(dom, item, 'id', path)
author = dom.createElement('author')
self.appendElement(dom, author, 'name', article.author.first_name + ' ' + article.author.last_name)
self.appendElement(dom, author, 'email', article.author.email)
item.appendChild(author)
filename = blog.src_path + '/_articles/' + str(article.id)
if not os.path.exists(filename):
self.addError('File does not exists ' + filename)
return
f = open(filename, 'rb')
article_content = '<![CDATA[' + f.read() + ']]>'
f.close()
self.appendElement(dom, item, 'summary', article_content, {'type':'html'})
self.appendElement(dom, item, 'content', article_content, {'type':'html'})
root.appendChild(item)
filename = 'atom.xml'
self.writeIfNotTheSame(output + '/' + filename, root)
if not self.somethingWrote:
self.addReport('Nothing changed')
return self.report

View File

@ -92,13 +92,13 @@ class DynastieGenerator:
return return
os.unlink(filename) os.unlink(filename)
self.addReport('Write ' + filename) self.addReport('Write (and compress) ' + filename)
f = open(filename,'wb') f = open(filename,'wb')
f.write(content) f.write(content)
f.close() f.close()
filename = filename + '.gz' filename = filename + '.gz'
self.addReport('Compressing it ' + filename) #self.addReport('Compressing it ' + filename)
f = gzip.open(filename, 'wb') f = gzip.open(filename, 'wb')
f.write(content) f.write(content)
f.close() f.close()

81
generators/rss.py Normal file
View File

@ -0,0 +1,81 @@
import os
import datetime
import xml
from dynastie.generators.generator import DynastieGenerator
from xml.dom.minidom import getDOMImplementation
from django.db import models
class RSS(DynastieGenerator):
def appendElement(self, dom, root, name='', content='', attributes=None):
elem = dom.createElement(name)
if not attributes is None:
for k, v in attributes.iteritems():
elem.setAttribute(k, v)
if content != '':
elem.appendChild(dom.createTextNode(content))
root.appendChild(elem)
return elem
def generate(self, blog, src, output):
from dynastie.models import Article, Blog
now = datetime.datetime.now()
impl = getDOMImplementation()
dom = impl.createDocument(None, "rss", None)
root = dom.documentElement
root.setAttribute('version', '2.0')
root.setAttributeNS('xmlns', 'xmlns:atom', 'http://www.w3.org/2005/Atom')
channel = dom.createElement('channel')
root.appendChild(channel)
self.appendElement(dom, channel, 'title', blog.title)
self.appendElement(dom, channel, 'description', blog.description)
self.appendElement(dom, channel, 'link', 'http://' + blog.name)
builddate = now.strftime('%a, %d %b %Y %H:%M:%S')
self.appendElement(dom, channel, 'lastBuildDate', builddate)
self.appendElement(dom, channel, 'generator', 'Dynastie')
self.appendElement(dom, channel, 'language', 'en-gb')
articles = Article.objects.filter(published=True).order_by('-creation_date')[:10]
for article in articles:
item = dom.createElement('item')
self.appendElement(dom, item, 'title', article.title)
path = 'http://' + blog.name + article.getPath()
self.appendElement(dom, item, 'link', path)
self.appendElement(dom, item, 'guid', path)
filename = blog.src_path + '/_articles/' + str(article.id)
if not os.path.exists(filename):
self.addError('File does not exists ' + filename)
return
f = open(filename, 'rb')
article_content = f.read()
f.close()
self.appendElement(dom, item, 'description', '<![CDATA[' + article_content + ']]>')
author = article.author.email
author += ' (' + article.author.first_name + ' ' + article.author.last_name + ')'
self.appendElement(dom, item, 'author', author)
self.appendElement(dom, item, 'category', article.category.name)
creationDate = article.creation_date.strftime('%a, %d %b %Y %H:%M:%S')
self.appendElement(dom, item, 'pubDate', creationDate)
channel.appendChild(item)
filename = 'rss.xml'
self.writeIfNotTheSame(output + '/' + filename, root)
if not self.somethingWrote:
self.addReport('Nothing changed')
return self.report

View File

@ -2,6 +2,7 @@ import os
import shutil import shutil
import hashlib import hashlib
import inspect import inspect
import gzip
from unicodedata import normalize from unicodedata import normalize
from re import sub from re import sub
from datetime import datetime from datetime import datetime
@ -77,6 +78,7 @@ class Blog(models.Model):
os.makedirs(dstname) os.makedirs(dstname)
self.copytree(srcname, dstname) self.copytree(srcname, dstname)
else: else:
copied = False
if os.path.exists(dstname): if os.path.exists(dstname):
src_md5 = hashlib.md5() src_md5 = hashlib.md5()
f = open(srcname,'rb') f = open(srcname,'rb')
@ -91,9 +93,31 @@ class Blog(models.Model):
if src_md5.digest() != dst_md5.digest(): if src_md5.digest() != dst_md5.digest():
self.report = self.report + 'Update ' + dstname + '<br/>\n' self.report = self.report + 'Update ' + dstname + '<br/>\n'
shutil.copy2(srcname, dstname) shutil.copy2(srcname, dstname)
copied = True
else: else:
self.report = self.report + 'Add ' + dstname + '<br/>\n' self.report = self.report + 'Add ' + dstname + '<br/>\n'
shutil.copy2(srcname, dstname) shutil.copy2(srcname, dstname)
copied = True
if copied:
exts = ('css', 'html', 'htm', 'xhtml', 'js')
found = False
for ext in exts:
if srname.endswith(ext):
found = True
break
if found:
dstname = dstname + '.gz'
if os.path.exists(dstname):
os.unlink(dstname)
f = open(srcname)
content = f.read()
f.close()
f = gzip.open(dstname, 'wb')
f.write(content)
f.close()
# XXX What about devices, sockets etc.? # XXX What about devices, sockets etc.?
except (IOError, os.error), why: except (IOError, os.error), why:

View File

@ -15,6 +15,7 @@
{% else %} {% else %}
{% autoescape off %} {% autoescape off %}
{{ report }} {{ report }}
<br/><br/>
{% endautoescape %} {% endautoescape %}
{% endif %} {% endif %}
{% if articles|length == 0 %} {% if articles|length == 0 %}
@ -23,7 +24,7 @@
{% else %} {% else %}
<table> <table>
{% for article in articles %} {% for article in articles %}
<hr><hl><a href="/article/edit/{{ article.id }}">{{ article.id }}</a></hl><hl>{{ article.title }}</hl><hl>{{ article.category.name }}</hl><hl>{{ article.creation_date }}</hl><hl>{{ article.published }}</hl><hl>{{ article.front_page }}</hl><hl><a href="/article/delete/{{ article.id }}">Delete</a></hl></hr> <tr><td><a href="/article/edit/{{ article.id }}">{{ article.id }}</a></td><td>{{ article.title }}</td><td>{{ article.category.name }}</td><td>{{ article.creation_date }}</td><td>{{ article.published }}</td><td>{{ article.front_page }}</td><td><a href="/article/delete/{{ article.id }}">Delete</a></td></tr>
{% endfor %} {% endfor %}
{% endif %} {% endif %}
</table> </table>

View File

@ -10,13 +10,14 @@
{% endif %} {% endif %}
<br/><br/> <br/><br/>
<a href="/article/add/{{ blog.id }}">Add an article</a> <a href="/generate/{{ blog.id }}">Generate blog</a> <a href="/article/add/{{ blog.id }}">Add an article</a> <a href="/generate/{{ blog.id }}">Generate blog</a>
<br/><br/>
{% if articles|length == 0 %} {% if articles|length == 0 %}
<br/><br/> <br/><br/>
<b>Any article available</b><br/><br/> <b>Any article available</b><br/><br/>
{% else %} {% else %}
<table> <table>
{% for article in articles %} {% for article in articles %}
<hr><hl><a href="/article/edit/{{ article.id }}">{{ article.id }}</a></hl><hl>{{ article.title }}</hl><hl>{{ article.category.name }}</hl><hl>{{ article.creation_date }}</hl><hl>{{ article.published }}</hl><hl>{{ article.front_page }}</hl><hl><a href="/article/delete/{{ article.id }}">Delete</a></hl></hr> <tr><td><a href="/article/edit/{{ article.id }}">{{ article.id }}</a></td><td>{{ article.title }}</td><td>{{ article.category.name }}</td><td>{{ article.creation_date }}</td><td>{{ article.published }}</td><td>{{ article.front_page }}</td><td><a href="/article/delete/{{ article.id }}">Delete</a></td></tr>
{% endfor %} {% endfor %}
{% endif %} {% endif %}
</table> </table>