check and update tags on save in editor
authorJan Szejko <janek37@gmail.com>
Thu, 20 Apr 2017 15:36:26 +0000 (17:36 +0200)
committerJan Szejko <janek37@gmail.com>
Thu, 20 Apr 2017 15:36:26 +0000 (17:36 +0200)
apps/catalogue/forms.py
apps/catalogue/models/document.py
apps/catalogue/models/tag.py
apps/wiki/forms.py
apps/wiki/views.py

index dc811ab..4b6a37b 100644 (file)
@@ -57,8 +57,7 @@ class TagForm(forms.Form):
     def save(self, instance=None):
         instance = instance or self.instance
         assert instance, 'No instance provided'
-        instance.tags.remove(*instance.tags.filter(category=self.category))
-        instance.tags.add(*self.cleaned_tags())
+        self.category.set_tags_for(instance, self.cleaned_tags())
 
     def field(self):
         raise NotImplementedError
index ef5a5cc..f190f5a 100755 (executable)
@@ -15,7 +15,43 @@ from django.utils.translation import ugettext_lazy as _
 from dvcs.models import Ref
 from organizations.models import Organization
 from catalogue.constants import STAGES
-from .tag import Tag
+from .tag import Tag, Category
+
+
+def metadata_from_text(text):
+    from lxml import etree
+    metadata = {}
+    text = text.replace(u'\ufeff', '')
+    # This is bad. The editor shouldn't spew unknown HTML entities.
+    text = text.replace(u'&nbsp;', u'\u00a0')
+
+    try:
+        t = etree.fromstring(text)
+    except:
+        return {'title': '<<Resource invalid>>'}
+    header = t.find('.//header')
+    if header is None:
+        header = etree.fromstring(text).find('.//{http://nowoczesnapolska.org.pl/sst#}header')
+    metadata['title'] = getattr(header, 'text', ' ') or ' '
+    # print 'meta', d['title']
+
+    m = t.find('metadata')
+    if m is None:
+        m = t.find('{http://nowoczesnapolska.org.pl/sst#}metadata')
+    if m is not None:
+        c = m.find('{http://purl.org/dc/elements/1.1/}relation.coverimage.url')
+        if c is not None:
+            metadata['cover_url'] = c.text
+        for category in Category.objects.all():
+            c = m.find('{http://purl.org/dc/elements/1.1/}' + category.dc_tag)
+            if c is not None:
+                if category.multiple:
+                    if category.dc_tag not in metadata:
+                        metadata[category.dc_tag] = []
+                    metadata[category.dc_tag].append(c.text)
+                else:
+                    metadata[category.dc_tag] = c.text
+    return metadata
 
 
 class Document(Ref):
@@ -41,36 +77,7 @@ class Document(Ref):
         return render_to_string('catalogue/book_list/book.html', {'book': self})
 
     def meta(self):
-        from lxml import etree
-        metadata = {}
-
-        data = self.materialize()
-        data = data.replace(u'\ufeff', '')
-        # This is bad. The editor shouldn't spew unknown HTML entities.
-        data = data.replace(u'&nbsp;', u'\u00a0')
-
-        try:
-            t = etree.fromstring(data)
-        except:
-            return {'title': '<<Resource invalid>>'}
-        header = t.find('.//header')
-        if header is None:
-            header = etree.fromstring(data).find('.//{http://nowoczesnapolska.org.pl/sst#}header')
-        metadata['title'] = getattr(header, 'text', ' ') or ' '
-        # print 'meta', d['title']
-
-        m = t.find('metadata')
-        if m is None:
-            m = t.find('{http://nowoczesnapolska.org.pl/sst#}metadata')
-        if m is not None:
-            c = m.find('{http://purl.org/dc/elements/1.1/}relation.coverimage.url')
-            if c is not None:
-                metadata['cover_url'] = c.text
-            c = m.find('{http://purl.org/dc/elements/1.1/}audience')
-            if c is not None:
-                metadata['audience'] = c.text
-
-        return metadata
+        return metadata_from_text(self.materialize())
 
     def can_edit(self, user):
         if user.is_superuser:
@@ -102,3 +109,15 @@ class Document(Ref):
     def is_overdue(self):
         plan = self.get_plan()
         return plan is not None and plan.deadline and plan.deadline < date.today()
+
+    def commit(self, *args, **kwargs):
+        super(Document, self).commit(*args, **kwargs)
+        m = self.meta()
+        for category in Category.objects.all():
+            values = m.get(category.dc_tag)
+            if not category.multiple:
+                values = [values]
+            if not values:
+                values = []
+            tags = category.tag_set.filter(dc_value__in=values)
+            category.set_tags_for(self, tags)
index b6341d0..aa73f86 100644 (file)
@@ -21,6 +21,10 @@ class Category(models.Model):
         verbose_name = _('category')
         verbose_name_plural = _('categories')
 
+    def set_tags_for(self, obj, tags):
+        obj.tags.remove(*obj.tags.filter(category=self))
+        obj.tags.add(*tags)
+
     def __unicode__(self):
         return self.label
 
index c2cb0ee..3cf5d11 100644 (file)
@@ -8,6 +8,8 @@ from django.core.exceptions import ValidationError
 from django.utils.translation import ugettext_lazy as _
 
 from catalogue.constants import STAGES
+from catalogue.models import Category
+from catalogue.models.document import metadata_from_text
 from librarian.document import Document
 
 
@@ -81,6 +83,16 @@ class DocumentTextSaveForm(forms.Form):
             if ext not in ('jpg', 'jpeg', 'png', 'gif', 'svg'):
                 raise ValidationError('Invalid cover image format, should be an image file (jpg, png, gif, svg). '
                                       'Change it in Metadata.')
+        metadata = metadata_from_text(text)
+        for category in Category.objects.all():
+            values = metadata.get(category.dc_tag)
+            if not category.multiple:
+                values = [values]
+            if not values:
+                values = []
+            for value in values:
+                if not category.tag_set.filter(dc_value=value):
+                    raise ValidationError('Invalid value for dc:%s: %s' % (category.dc_tag, value))
         return text
 
 
index e0e2f08..da747cc 100644 (file)
@@ -108,9 +108,6 @@ def text(request, doc_id):
             # else:
             #     parent = None
             stage = form.cleaned_data['stage']
-            # tags = [stage] if stage else []
-            # publishable = (form.cleaned_data['publishable'] and
-            #                request.user.has_perm('catalogue.can_pubmark'))
             try:
                 doc.commit(
                     author=author,