Dynastie/models.py

218 lines
7.5 KiB
Python

import os
import shutil
import hashlib
import inspect
from unicodedata import normalize
from re import sub
from datetime import datetime
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_init, post_delete, post_save
from django.dispatch import receiver
from dynastie.generators import *
class Blog(models.Model):
name = models.CharField(max_length=255, unique=True)
title = models.CharField(max_length=255)
description = models.TextField(max_length=255, blank=True)
keywords = models.TextField(blank=True)
writers = models.ManyToManyField(User)
engines = list()
src_path = ''
output_path = ''
report = ''
def create_paths(self):
self.src_path = 'sites/' + self.name
self.output_path = 'sites/' + self.name + '_output'
def create(self):
self.create_paths()
if not os.path.exists('sites'):
os.mkdir('sites')
if not os.path.exists(self.src_path):
os.mkdir(self.src_path)
if not os.path.exists(self.output_path):
os.mkdir(self.output_path)
def remove(self):
if os.path.exists(self.src_path):
shutil.rmtree(self.src_path)
if os.path.exists(self.output_path):
shutil.rmtree(self.output_path)
def load_generators(self):
if os.path.exists(self.src_path + '/_generators'):
f = open(self.src_path + '/_generators', 'r')
for line in f:
self.engines.append(globals()[line.strip()])
f.close()
else:
self.engines.append(globals()['index'])
self.engines.append(globals()['categories'])
self.engines.append(globals()['archives'])
def copytree(self, src, dst):
names = os.listdir(src)
errors = []
for name in names:
if name.startswith('_') or name.endswith('~'):
continue
srcname = os.path.join(src, name)
dstname = os.path.join(dst, name)
try:
if os.path.islink(srcname) and not os.path.exists(dstname):
linkto = os.readlink(srcname)
os.symlink(linkto, dstname)
if os.path.isdir(srcname):
if not os.path.exists(dstname):
os.makedirs(dstname)
self.copytree(srcname, dstname)
else:
if os.path.exists(dstname):
src_md5 = hashlib.md5()
f = open(srcname,'rb')
src_md5.update(f.read())
f.close()
dst_md5 = hashlib.md5()
f = open(dstname,'rb')
dst_md5.update(f.read())
f.close()
if src_md5.digest() != dst_md5.digest():
self.report = self.report + 'Update ' + dstname + '<br/>\n'
shutil.copy2(srcname, dstname)
else:
self.report = self.report + 'Add ' + dstname + '<br/>\n'
shutil.copy2(srcname, dstname)
# XXX What about devices, sockets etc.?
except (IOError, os.error), why:
errors.append((srcname, dstname, str(why)))
# catch the Error from the recursive copytree so that we can
# continue with other files
except Exception, err:
errors.extend(err.args[0])
if errors:
raise Exception(errors)
def generate(self):
self.report = '<br/><br/>Generation of ' + datetime.now().strftime("%d/%m/%Y at %H:%M:%S") + '<br/>\n'
self.load_generators()
self.copytree(self.src_path, self.output_path)
for engine in self.engines:
for name, obj in inspect.getmembers(engine):
if inspect.isclass(obj):
e = obj()
r = e.generate(self, self.src_path, self.output_path)
if not r is None:
self.report = self.report + '<br/>\n' + r
return self.report
class Editor(models.Model):
name = models.CharField(max_length=255, unique=True)
class Category(models.Model):
name = models.CharField(max_length=255, unique=True)
parent = models.ForeignKey('self', blank=True, null=True)
description = models.TextField(max_length=255, blank=True)
class Tag(models.Model):
name = models.CharField(max_length=255, unique=True)
class Article(models.Model):
title = models.CharField(max_length=255)
title_slug = models.CharField(max_length=255)
category = models.ForeignKey(Category, blank=True, null=True, on_delete=models.SET_NULL)
published = models.BooleanField()
creation_date = models.DateField()
front_page = models.BooleanField()
author = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
description = models.TextField(max_length=255, blank=True)
keywords = models.TextField(blank=True)
tags = models.ManyToManyField(Tag, blank=True, null=True)
blog = models.ForeignKey(Blog)
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()
super(Article, self).save()
def createArticle(self, content):
b = self.blog
b.create_paths()
output = b.src_path
if not os.path.exists(output + '/_articles'):
os.mkdir(output + '/_articles')
filename = output + '/_articles/' + str(self.pk)
if os.path.exists(filename):
os.unlink(filename)
f = open(filename, 'wb')
f.write(content)
f.close()
def remove(self):
b = self.blog
b.create_paths()
output = b.src_path
filename = output + '/_articles/' + str(self.pk)
if os.path.exists(filename):
os.unlink(filename)
output = b.output_path
filename = output + '/articles/'
filename = filename + self.creation_date.strftime("%Y") + '/' + self.creation_date.strftime("%m") + '/'
filename = filename + self.title_slug + '.html'
if os.path.exists(filename):
os.unlink(filename)
filename = filename + '.gz'
if os.path.exists(filename):
os.unlink(filename)
filename = output + '/articles/'
filename = filename + self.creation_date.strftime("%Y") + '/' + self.creation_date.strftime("%m") + '/'
if len(os.listdir(filename)) == 0:
os.rmdir(filename)
filename = output + '/articles/'
filename = filename + self.creation_date.strftime("%Y") + '/'
if len(os.listdir(filename)) == 0:
os.rmdir(filename)
class Comment(models.Model):
article = models.ForeignKey(Article)
parent = models.ForeignKey('Comment')
date = models.DateField(max_length=255)
author = models.CharField(max_length=255)
email = models.EmailField(max_length=255)
the_comment = models.TextField(max_length=255)
@receiver(post_init, sender=Blog)
def delete_blog_signal(sender, **kwargs):
sender.create_paths()
@receiver(post_delete, sender=Blog)
def delete_blog_signal(sender, **kwargs):
sender.remove()
@receiver(post_delete, sender=Article)
def delete_article_signal(sender, **kwargs):
sender.remove()