Skip to content

Commit

Permalink
Merge pull request #2330 from laws-africa/provision-level-pit-comparison
Browse files Browse the repository at this point in the history
Provision-level PiT comparison
  • Loading branch information
goose-life authored Jan 23, 2025
2 parents 7faf6b8 + 2de2e2c commit 3d6e08a
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 26 deletions.
4 changes: 2 additions & 2 deletions indigo_api/models/documents.py
Original file line number Diff line number Diff line change
Expand Up @@ -548,14 +548,14 @@ def change_date(self, new_date, user, comment=None):
self.expression_date = new_date
self.save_with_revision(user, comment=comment)

def get_provision_element(self, provision_eid):
def get_portion(self, provision_eid):
provision_xml = self.doc.get_portion_element(provision_eid)
if provision_xml is None:
return None
portion = StructuredDocument.for_document_type('portion')()
portion.frbr_uri = self.frbr_uri
portion.main_content.append(provision_xml)
return portion.main
return portion

def update_provision_xml(self, provision_eid, provision_xml):
xml = etree.fromstring(provision_xml)
Expand Down
14 changes: 2 additions & 12 deletions indigo_api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,7 @@ class DocumentAPISerializer(serializers.Serializer):
xml = serializers.CharField()
language = serializers.CharField(min_length=3, max_length=3)
provision_eid = serializers.CharField(allow_blank=True)
element_id = serializers.CharField(required=False, allow_null=True, allow_blank=True)

def validate_xml(self, xml):
""" mostly copied from DocumentSerializer.validate()
Expand Down Expand Up @@ -488,7 +489,7 @@ def updated_xml(self):
return document.document_xml
# otherwise, return only the provision being edited (NOT including the outer akn tag)
# if we used the full XML for the analysis, grab only the appropriate provision as a portion
xml = document.get_provision_element(provision_eid) if self.use_full_xml else document.doc.portion
xml = document.get_portion(provision_eid).main if self.use_full_xml else document.doc.portion
return etree.tostring(xml, encoding='unicode')


Expand Down Expand Up @@ -714,14 +715,3 @@ def get_url(self, instance):
'work_id': instance.amended_work.pk,
'pk': instance.pk,
})


class DocumentDiffSerializer(serializers.Serializer):
""" Helper to handle input elements for the /document/xxx/diff API
"""
document = DocumentSerializer(required=True)
element_id = serializers.CharField(required=False, allow_null=True)

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['document'].instance = self.instance
27 changes: 21 additions & 6 deletions indigo_api/views/documents.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,15 @@
from django_filters.rest_framework import DjangoFilterBackend
from cobalt import StructuredDocument

from lxml import etree
import lxml.html.diff

from indigo.analysis.differ import AKNHTMLDiffer
from indigo.analysis.refs.base import markup_document_refs
from indigo.plugins import plugins
from indigo.xmlutils import parse_html_str
from ..models import Document, Annotation, DocumentActivity, Task, Language, Work
from ..serializers import DocumentSerializer, RenderSerializer, ParseSerializer, DocumentAPISerializer, VersionSerializer, AnnotationSerializer, DocumentActivitySerializer, TaskSerializer, DocumentDiffSerializer
from ..models import Document, Annotation, DocumentActivity, Task
from ..serializers import DocumentSerializer, RenderSerializer, ParseSerializer, DocumentAPISerializer, VersionSerializer, AnnotationSerializer, DocumentActivitySerializer, TaskSerializer
from ..renderers import AkomaNtosoRenderer, PDFRenderer, EPUBRenderer, HTMLRenderer, ZIPRenderer
from indigo_api.exporters import HTMLExporter
from ..authz import DocumentPermissions, AnnotationPermissions, ModelPermissions, RelatedDocumentPermissions, \
Expand Down Expand Up @@ -424,7 +425,8 @@ def manipulate_xml(self):

class DocumentDiffView(DocumentResourceView, APIView):
def post(self, request, document_id):
serializer = DocumentDiffSerializer(instance=self.document, data=self.request.data)
serializer = DocumentAPISerializer(instance=self.document, data=self.request.data)
serializer.use_full_xml = False
serializer.is_valid(raise_exception=True)

differ = AKNHTMLDiffer()
Expand All @@ -433,10 +435,23 @@ def post(self, request, document_id):

# set this up to be the modified document
remote_doc = Document.objects.get(pk=local_doc.pk)
serializer.fields['document'].update_document(local_doc, serializer.validated_data['document'])

local_doc.content = differ.preprocess_xml_str(local_doc.document_xml).decode('utf-8')
remote_doc.content = differ.preprocess_xml_str(remote_doc.document_xml).decode('utf-8')
# this will set the local_doc's content as the <portion> in provision mode,
# and update it with the latest unsaved changes regardless
serializer.set_content()
local_doc.content = differ.preprocess_xml_str(local_doc.document_xml)

provision_eid = serializer.validated_data.get('provision_eid')
if provision_eid:
portion = remote_doc.get_portion(provision_eid)
# the same structure as the 'xml' we're getting from the browser: akn/portion/portionBody/element
remote_xml = etree.tostring(portion.root, encoding='unicode')
remote_doc.work.work_uri.doctype = 'portion'
remote_doc.content = differ.preprocess_xml_str(remote_xml)

else:
# full document mode
remote_doc.content = differ.preprocess_xml_str(remote_doc.document_xml)

element_id = serializer.validated_data.get('element_id')
if element_id:
Expand Down
7 changes: 3 additions & 4 deletions indigo_app/static/javascript/indigo/views/document_editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -262,13 +262,12 @@
},

renderComparisonDiff: function() {
var self = this,
data = {};
let self = this;

if (!this.comparisonDocumentId) return;

data.document = this.document.toJSON();
data.document.content = this.document.content.toXml();
const data = this.document.content.toSimplifiedJSON();
// slight difference to provision_eid -- doesn't treat the document XML as a portion
data.element_id = this.xmlElement.getAttribute('eId');

if (!data.element_id && this.xmlElement.tagName !== "akomaNtoso") {
Expand Down
5 changes: 3 additions & 2 deletions indigo_app/views/documents.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,11 @@ class DocumentProvisionDetailView(DocumentDetailView):
def get(self, request, *args, **kwargs):
document = self.get_object()
self.eid = self.kwargs.get('eid')
self.provision_xml = document.get_provision_element(self.eid)
if self.provision_xml is None:
provision_xml = document.get_portion(self.eid)
if provision_xml is None:
messages.error(request, _("No provision with this id found: '%(eid)s'") % {"eid": self.eid})
return redirect('choose_document_provision', doc_id=document.id)
self.provision_xml = provision_xml.main
return super().get(request, *args, **kwargs)

def get_context_data(self, **kwargs):
Expand Down

0 comments on commit 3d6e08a

Please sign in to comment.