1 # -*- coding: utf-8 -*-
3 # This file is part of MIL/PEER, licensed under GNU Affero GPLv3 or later.
4 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
6 from __future__ import unicode_literals
8 from datetime import date
9 from django.conf import settings
10 from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
11 from django.db import models
12 from django.template.loader import render_to_string
13 from django.utils.encoding import force_unicode
14 from django.utils.translation import ugettext_lazy as _
15 from dvcs.models import Ref
16 from organizations.models import Organization
17 from catalogue.constants import STAGES
18 from .tag import Tag, Category
21 def metadata_from_text(text):
22 from lxml import etree
24 text = text.replace(u'\ufeff', '')
25 # This is bad. The editor shouldn't spew unknown HTML entities.
26 text = text.replace(u' ', u'\u00a0')
29 t = etree.fromstring(text)
31 return {'title': '<<Resource invalid>>'}
32 header = t.find('.//header')
34 header = etree.fromstring(text).find('.//{http://nowoczesnapolska.org.pl/sst#}header')
35 metadata['title'] = getattr(header, 'text', ' ') or ' '
36 # print 'meta', d['title']
38 m = t.find('metadata')
40 m = t.find('{http://nowoczesnapolska.org.pl/sst#}metadata')
42 c = m.find('{http://purl.org/dc/elements/1.1/}relation.coverimage.url')
44 metadata['cover_url'] = c.text
45 for category in Category.objects.all():
46 c = m.find('{http://purl.org/dc/elements/1.1/}' + category.dc_tag)
49 if category.dc_tag not in metadata:
50 metadata[category.dc_tag] = []
51 metadata[category.dc_tag].append(c.text)
53 metadata[category.dc_tag] = c.text
58 """ An editable chunk of text."""
60 owner_user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True)
61 owner_organization = models.ForeignKey(Organization, null=True)
62 stage = models.CharField(_('stage'), max_length=128, blank=True, default=STAGES[0][0])
63 assigned_to = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, related_name='assignments')
64 deleted = models.BooleanField(default=False)
65 tags = models.ManyToManyField(Tag, blank=True)
66 # we need to know if it were ever published (for notifications)
67 published = models.BooleanField(default=False)
69 # Where to cache searchable stuff from metadata?
70 # Probably in some kind of search index.
73 verbose_name = _('document')
74 verbose_name_plural = _('documents')
77 return render_to_string('catalogue/book_list/book.html', {'book': self})
80 return metadata_from_text(self.materialize())
82 def can_edit(self, user):
86 return self.owner_user == user
88 return self.owner_organization.is_member(user)
90 def set_stage(self, stage):
92 plan = self.get_plan()
94 self.assigned_to = plan.user
96 self.assigned_to = None
100 return force_unicode(dict(STAGES)[self.stage]) if self.stage else None
104 plan = self.plan_set.get(stage=self.stage)
105 except (ObjectDoesNotExist, MultipleObjectsReturned):
109 def is_overdue(self):
110 plan = self.get_plan()
111 return plan is not None and plan.deadline and plan.deadline < date.today()
113 def commit(self, *args, **kwargs):
114 super(Document, self).commit(*args, **kwargs)
116 for category in Category.objects.all():
117 values = m.get(category.dc_tag)
118 if not category.multiple:
122 tags = category.tag_set.filter(dc_value__in=values)
123 category.set_tags_for(self, tags)