5fa6242e2c7e97f0757b6457cc1e72fb7d87a7fc
[redakcja.git] / apps / catalogue / models / document.py
1 # -*- coding: utf-8 -*-
2 #
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.
5 #
6 from __future__ import unicode_literals
7
8 from datetime import date
9 from django.conf import settings
10 from django.db import models
11 from django.template.loader import render_to_string
12 from django.utils.translation import ugettext_lazy as _
13 from dvcs.models import Ref
14 from organizations.models import Organization
15 from catalogue.constants import STAGES
16 from .tag import Tag
17
18
19 class Document(Ref):
20     """ An editable chunk of text."""
21
22     owner_user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True)
23     owner_organization = models.ForeignKey(Organization, null=True)
24     stage = models.CharField(_('stage'), max_length=128, blank=True, default=STAGES[0])
25     assigned_to = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, related_name='assignments')
26     deleted = models.BooleanField(default=False)
27     tags = models.ManyToManyField(Tag)
28
29     # Where to cache searchable stuff from metadata?
30     # Probably in some kind of search index.
31
32     class Meta:
33         verbose_name = _('document')
34         verbose_name_plural = _('documents')
35
36     def short_html(self):
37         return render_to_string('catalogue/book_list/book.html', {'book': self})
38
39     def meta(self):
40         from lxml import etree
41         # Wrong! should be metadata
42         d = {}
43
44         data = self.materialize()
45         data = data.replace(u'\ufeff', '')
46         # This is bad. The editor shouldn't spew unknown HTML entities.
47         data = data.replace(u' ', u'\u00a0')
48
49         try:
50             t = etree.fromstring(data)
51         except:
52             return {'title': '<<Resource invalid>>'}
53         header = t.find('.//header')
54         if header is None:
55             header = etree.fromstring(data).find('.//{http://nowoczesnapolska.org.pl/sst#}header')
56         d['title'] = getattr(header, 'text', ' ') or ' '
57         #print 'meta', d['title']
58
59         m = t.find('metadata')
60         if m is None:
61             m = t.find('{http://nowoczesnapolska.org.pl/sst#}metadata')
62         if m is not None:
63             c = m.find('{http://purl.org/dc/elements/1.1/}relation.coverimage.url')
64             if c is not None:
65                 d['cover_url'] = c.text
66             c = m.find('{http://purl.org/dc/elements/1.1/}audience')
67             if c is not None:
68                 d['audience'] = c.text
69
70         return d
71
72     def can_edit(self, user):
73         if self.owner_user:
74             return self.owner_user == user
75         else:
76             return self.owner_organization.is_member(user)
77
78     def set_stage(self, stage):
79         self.stage = stage
80         plan = self.get_plan()
81         if plan is not None:
82             self.assigned_to = plan.user
83         else:
84             self.assigned_to = None
85         self.save()
86
87     def get_plan(self):
88         try:
89             plan = self.plan_set.get(stage=self.stage)
90         except:
91             return None
92         return plan
93
94     def is_overdue(self):
95         plan = self.get_plan()
96         return plan is not None and plan.deadline and plan.deadline < date.today()