# -*- coding: utf-8 -*- # vi:si:et:sw=4:sts=4:ts=4 # Written 2009 by j@mailb.org import os import re from glob import glob import oxlib import oxlib.normalize from django.db import models from django.conf import settings def getAuthor(name, name_sort=''): try: a = Author.objects.get(name=name) except Author.DoesNotExist: a = Author(name=name, name_sort=name_sort) a.save() return a class Author(models.Model): name = models.CharField(blank=True, max_length=255, unique=True) name_sort = models.CharField('Sort Name', blank=True, max_length=1000) class Meta: ordering = ('name_sort', ) def __unicode__(self): return self.name def save(self, *args, **kwargs): if not self.name_sort: self.name_sort = oxlib.normalize.canonicalName(self.name) super(Author, self).save(*args, **kwargs) #update path in related texts for text in self.texts.all(): text.save() class AuthorField(models.ManyToManyField): def save_form_data(self, instance, data): super(AuthorField, self).save_form_data(instance, data) #save instance after adding authors, file gets updated here instance.save() class Language(models.Model): name = models.CharField(blank=True, max_length=1000) class Meta: ordering = ('name', ) def __unicode__(self): return self.name class Text(models.Model): created = models.DateTimeField(auto_now_add=True) updated = models.DateTimeField(auto_now=True) title = models.CharField(blank=True, max_length=1000) version = models.CharField(blank=True, max_length=1000) file = models.FileField(upload_to='tmp', blank=True, max_length=2000) authors = AuthorField(Author, related_name='texts', blank=True) languages = models.ManyToManyField(Language, related_name='texts', blank=True) compilation = models.BooleanField(default=False) class Meta: ordering = ('file', 'title', 'version') def __unicode__(self): return self.title def getComputedPath(self): authors = [a.name_sort for a in self.authors.all()] author = "; ".join(authors) if not author: author = "Unknown Author" if self.compilation: author += " (Ed.)" elif author.endswith("."): author = author[:-1] + "_" title = self.title title = re.sub('[:/]', '_', title) if self.version: title += ".%s" % self.version extension = os.path.splitext(self.file.path)[1].lower() path = u"%s/%s/%s%s" % (author[0].upper(), author, title, extension) return os.path.join(settings.MEDIA_ROOT, path).encode('utf-8') def parsePath(self): if self.file: match = re.compile('./(.*)/(.*)').findall(self.file.name) title = os.path.splitext(match[0][1])[0] compilation = False #FIXME: parse version version = re.compile("\.(\w+)$").findall(title) if version: version = version[0] title = title[:-(len(version) + 1)] else: version = '' authors = match[0][0] if authors.endswith("_"): authors = authors[:-1] + "." if authors.endswith(' (Ed.)'): authors = authors[:-len(' (Ed.)')] compilation = True if authors != 'Unknown Author': authors = [(oxlib.normalize.normalizeName(a), a) for a in authors.split("; ")] else: authors = [] self.title = title self.version = version self.compilation = compilation self.save(rename=False) for a in authors: author = getAuthor(a[0], a[1]) self.authors.add(author) self.save() def save(self, *args, **kwargs): rename = True if "rename" in kwargs: rename = kwargs['rename'] del kwargs['rename'] super(Text, self).save(*args, **kwargs) if rename and self.file: path = self.getComputedPath() if path != self.file.path: #FIXME: make sure path is not used by other test in system if not os.path.exists(os.path.dirname(path)): os.makedirs(os.path.dirname(path)) old_dir = os.path.dirname(self.file.path) #print 'old', self.file.path #print 'new', path os.rename(self.file.path, path) if not glob('%s/*' % old_dir): os.rmdir(old_dir) self.file.name = path[len(settings.MEDIA_ROOT) + 1:] self.save(rename=False)