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:
parent
a5c5e7edc8
commit
e270a52e41
|
@ -1 +1 @@
|
||||||
__all__ = ["generator", "index", "article", "category", "archive"]
|
__all__ = ["generator", "index", "article", "category", "archive", "rss", "atom"]
|
||||||
|
|
73
generators/atom.py
Normal file
73
generators/atom.py
Normal 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
|
||||||
|
|
|
@ -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
81
generators/rss.py
Normal 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
|
||||||
|
|
24
models.py
24
models.py
|
@ -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:
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user