From b6d961cf3b454e6fcc9365a1121c34501f5f9106 Mon Sep 17 00:00:00 2001 From: Jan Szejko Date: Thu, 20 Apr 2017 17:36:26 +0200 Subject: [PATCH] check and update tags on save in editor --- apps/catalogue/forms.py | 3 +- apps/catalogue/models/document.py | 81 +++++++++++++++++++------------ apps/catalogue/models/tag.py | 4 ++ apps/wiki/forms.py | 12 +++++ apps/wiki/views.py | 3 -- 5 files changed, 67 insertions(+), 36 deletions(-) diff --git a/apps/catalogue/forms.py b/apps/catalogue/forms.py index dc811ab4..4b6a37bb 100644 --- a/apps/catalogue/forms.py +++ b/apps/catalogue/forms.py @@ -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 diff --git a/apps/catalogue/models/document.py b/apps/catalogue/models/document.py index ef5a5ccf..f190f5a0 100755 --- a/apps/catalogue/models/document.py +++ b/apps/catalogue/models/document.py @@ -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' ', u'\u00a0') + + try: + t = etree.fromstring(text) + except: + return {'title': '<>'} + 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' ', u'\u00a0') - - try: - t = etree.fromstring(data) - except: - return {'title': '<>'} - 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) diff --git a/apps/catalogue/models/tag.py b/apps/catalogue/models/tag.py index b6341d01..aa73f865 100644 --- a/apps/catalogue/models/tag.py +++ b/apps/catalogue/models/tag.py @@ -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 diff --git a/apps/wiki/forms.py b/apps/wiki/forms.py index c2cb0eef..3cf5d11c 100644 --- a/apps/wiki/forms.py +++ b/apps/wiki/forms.py @@ -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 diff --git a/apps/wiki/views.py b/apps/wiki/views.py index e0e2f085..da747ccc 100644 --- a/apps/wiki/views.py +++ b/apps/wiki/views.py @@ -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, -- 2.20.1