diff --git a/CHANGELOG.md b/CHANGELOG.md index 56627d64..54a95c28 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +v0.8.5 +======= + * Add transcript link to Document API serializer + * Add 'Add/Edit Transcript' button to Document editing view + * Hide Note and Attachment fields from Zotero editing form + v0.8.4 ======= * Allow draggable widgets to work on tablets diff --git a/editorsnotes/admin/templates/admin_base.html b/editorsnotes/admin/templates/admin_base.html index ed705482..7780c431 100644 --- a/editorsnotes/admin/templates/admin_base.html +++ b/editorsnotes/admin/templates/admin_base.html @@ -3,7 +3,6 @@ {% load display staticfiles %} {% block js %} - {% if form.media %}{{ form.media.js }}{% endif %} {% endblock %} diff --git a/editorsnotes/admin/views/common.py b/editorsnotes/admin/views/common.py index c6126c4c..e8adc5a6 100644 --- a/editorsnotes/admin/views/common.py +++ b/editorsnotes/admin/views/common.py @@ -126,19 +126,19 @@ def get_context_data(self, **kwargs): context['bootstrap'] = 'null'; return context -class BaseAdminView(ProcessInlineFormsetsView, ProjectSpecificMixin, - ModelFormMixin, BreadcrumbMixin, TemplateResponseMixin): +class BaseAdminView(ProjectSpecificMixin, BreadcrumbMixin, ModelFormMixin, + TemplateResponseMixin, ProcessInlineFormsetsView): def get_form_kwargs(self): kwargs = super(ModelFormMixin, self).get_form_kwargs() if hasattr(self, 'object') and self.object: kwargs.update({'instance': self.object}) else: - has_project_field = all([ - hasattr(self.model, 'project'), - hasattr(self.model.project, 'field'), - hasattr(self.model.project.field, 'related'), - self.model.project.field.related.parent_model == Project - ]) + has_project_field = ( + hasattr(self.model, 'project') + and hasattr(self.model.project, 'field') + and hasattr(self.model.project.field, 'related') + and self.model.project.field.related.parent_model == Project + ) if has_project_field: # Then create an instance with the project already set instance = self.model(project=self.project) diff --git a/editorsnotes/admin/views/documents.py b/editorsnotes/admin/views/documents.py index 8c8d6631..46e7e7ff 100644 --- a/editorsnotes/admin/views/documents.py +++ b/editorsnotes/admin/views/documents.py @@ -85,3 +85,12 @@ def save_footnote_formset_form(self, form): a = transcript.content.cssselect('a.footnote[href$="%s"]' % stamp)[0] a.attrib['href'] = footnote.get_absolute_url() transcript.save() + def get_breadcrumb(self): + breadcrumbs = ( + (self.document.project.name, self.document.project.get_absolute_url()), + ('Documents', reverse('all_documents_view', + kwargs={'project_slug': self.project.slug})), + (self.document.as_text(), self.document.get_absolute_url()), + ('Edit transcript', None) + ) + return breadcrumbs diff --git a/editorsnotes/api/serializers/__init__.py b/editorsnotes/api/serializers/__init__.py index 234bd2cb..b810c387 100644 --- a/editorsnotes/api/serializers/__init__.py +++ b/editorsnotes/api/serializers/__init__.py @@ -1,3 +1,3 @@ -from documents import DocumentSerializer, ScanSerializer +from documents import DocumentSerializer, ScanSerializer, TranscriptSerializer from topics import TopicSerializer from notes import NoteSerializer diff --git a/editorsnotes/api/serializers/documents.py b/editorsnotes/api/serializers/documents.py index 49895de0..dd19a01b 100644 --- a/editorsnotes/api/serializers/documents.py +++ b/editorsnotes/api/serializers/documents.py @@ -3,8 +3,9 @@ from lxml import etree from rest_framework import serializers +from rest_framework.reverse import reverse -from editorsnotes.main.models import Document, Citation, Scan +from editorsnotes.main.models import Document, Citation, Scan, Transcript from .base import (RelatedTopicSerializerMixin, ProjectSpecificItemMixin, URLField, ProjectSlugField, HyperlinkedProjectItemField) @@ -37,9 +38,10 @@ class Meta: class DocumentSerializer(RelatedTopicSerializerMixin, ProjectSpecificItemMixin, serializers.ModelSerializer): + url = URLField() project = ProjectSlugField() + transcript = serializers.SerializerMethodField('get_transcript_url') zotero_data = ZoteroField(required=False) - url = URLField() scans = ScanSerializer(many=True, required=False, read_only=True) def get_validation_exclusions(self): # TODO: This can be removed in future versions of django rest framework. @@ -49,10 +51,23 @@ def get_validation_exclusions(self): exclusions = super(DocumentSerializer, self).get_validation_exclusions() exclusions.remove('zotero_data') return exclusions + def get_transcript_url(self, obj): + if not obj.has_transcript(): + return None + return reverse('api:api-transcripts-detail', + args=(obj.project.slug, obj.id), + request=self.context.get('request', None)) class Meta: model = Document fields = ('id', 'description', 'url', 'project', 'last_updated', - 'scans', 'related_topics', 'zotero_data',) + 'scans', 'transcript', 'related_topics', 'zotero_data',) + +class TranscriptSerializer(serializers.ModelSerializer): + url = URLField(lookup_arg_attrs=('document.project.slug', 'document.id')) + document = HyperlinkedProjectItemField( + required=True, view_name='api:api-documents-detail') + class Meta: + model = Transcript class CitationSerializer(serializers.ModelSerializer): url = URLField('api:api-topic-citations-detail', diff --git a/editorsnotes/api/urls.py b/editorsnotes/api/urls.py index 43642a74..3626c9ad 100644 --- a/editorsnotes/api/urls.py +++ b/editorsnotes/api/urls.py @@ -30,6 +30,8 @@ url(r'^documents/(?P\d+)/scans/$', views.ScanList.as_view(), name='api-scans-list'), url(r'^documents/(?P\d+)/scans/(?P\d+)/$', views.ScanDetail.as_view(), name='api-scans-detail'), url(r'^documents/(?P\d+)/scans/normalize_order/$', views.NormalizeScanOrder.as_view(), name='api-scans-normalize-order'), + + url(r'^documents/(?P\d+)/transcript/$', views.Transcript.as_view(), name='api-transcripts-detail'), ) urlpatterns = patterns('', diff --git a/editorsnotes/api/views/documents.py b/editorsnotes/api/views/documents.py index 759e2075..cd30538e 100644 --- a/editorsnotes/api/views/documents.py +++ b/editorsnotes/api/views/documents.py @@ -3,15 +3,16 @@ from rest_framework.response import Response from rest_framework.views import APIView -from editorsnotes.main.models import Document, Scan +from editorsnotes.main.models import Document, Scan, Transcript from .base import (BaseListAPIView, BaseDetailView, DeleteConfirmAPIView, ElasticSearchListMixin, ProjectSpecificMixin) from ..permissions import ProjectSpecificPermissions -from ..serializers import DocumentSerializer, ScanSerializer +from ..serializers import (DocumentSerializer, ScanSerializer, + TranscriptSerializer) __all__ = ['DocumentList', 'DocumentDetail', 'DocumentConfirmDelete', - 'ScanList', 'ScanDetail', 'NormalizeScanOrder'] + 'ScanList', 'ScanDetail', 'NormalizeScanOrder', 'Transcript'] class DocumentList(ElasticSearchListMixin, BaseListAPIView): model = Document @@ -90,3 +91,15 @@ def get_queryset(self): document_qs = Document.objects.prefetch_related('scans__creator') document = get_object_or_404(document_qs, id=document_id) return document.scans.filter(id=scan_id) + +class Transcript(BaseDetailView): + model = Transcript + serializer_class = TranscriptSerializer + def get_object(self, queryset=None): + transcript_qs = self.model.objects\ + .select_related('document__project')\ + .filter( + document__id=self.kwargs.get('document_id'), + document__project__slug=self.kwargs.get('project_slug') + ) + return get_object_or_404(transcript_qs) diff --git a/editorsnotes_app/js/templates/document.html b/editorsnotes_app/js/templates/document.html index 540d47a3..bcc4b1a1 100644 --- a/editorsnotes_app/js/templates/document.html +++ b/editorsnotes_app/js/templates/document.html @@ -27,3 +27,12 @@

Related topics

+ +<% if (!doc.isNew()) { %> +
+

Transcript

+ <% var transcript_url = doc.get('url').replace('/api/', '/') + 'transcript/edit/'; %> + <% var transcript_action = doc.get('transcript') ? 'Edit' : 'Add'; %> + <%= transcript_action %> transcript +
+<% } %> diff --git a/editorsnotes_app/js/templates/zotero_item.html b/editorsnotes_app/js/templates/zotero_item.html index c05d6f8b..a62692dd 100644 --- a/editorsnotes_app/js/templates/zotero_item.html +++ b/editorsnotes_app/js/templates/zotero_item.html @@ -8,7 +8,7 @@
<%= i18n.translate(val).fetch() %>
- <% } else if (key === 'tags') { %> + <% } else if (key === 'tags' || key === 'attachments' || key === 'notes') { %> <% _(val).forEach(function (tag) { %>