def autoshare_delete(request, record, carenet): """ Remove an autoshare from a carenet. request.POST must contain: * *type*: the document schema namespace to remove an autoshare for This will effectively unshare all documents of type *type* from the carenet, except documents which were shared individually. Will return :http:statuscode:`200` on sucess, :http:statuscode:`404` if the specified *type* doesn't exist. """ TYPE = 'type' if request.POST.has_key(TYPE): try: docschema = DocumentSchema.objects.get(type = DocumentProcessing.expand_schema(request.POST[TYPE])) except DocumentSchema.DoesNotExist: raise Http404 CarenetAutoshare.objects.filter(record = record, carenet = carenet, type = docschema).delete() return DONE
def autoshare_delete(request, record, carenet): """ Remove an autoshare from a carenet. request.POST must contain: * *type*: the document schema namespace to remove an autoshare for This will effectively unshare all documents of type *type* from the carenet, except documents which were shared individually. Will return :http:statuscode:`200` on sucess, :http:statuscode:`404` if the specified *type* doesn't exist. """ TYPE = 'type' if request.POST.has_key(TYPE): try: docschema = DocumentSchema.objects.get( type=DocumentProcessing.expand_schema(request.POST[TYPE])) except DocumentSchema.DoesNotExist: raise Http404 CarenetAutoshare.objects.filter(record=record, carenet=carenet, type=docschema).delete() return DONE
def autoshare_list(request, record): """ For a single record, list all carenets that a given doctype is autoshared with. request.GET must contain: * *type*: the document schema namespace to check autoshares for Will return :http:statuscode:`200` with a list of carenets that have an autoshare set up for doctype *type* on success, :http:statuscode:`404` if the specified *type* doesn't exist. """ TYPE = 'type' autoshares = [] if request.GET.has_key(TYPE): try: docschema = DocumentSchema.objects.get( type=DocumentProcessing.expand_schema(request.GET[TYPE])) except DocumentSchema.DoesNotExist: raise Http404 carenets = [ autoshare.carenet for autoshare in CarenetAutoshare.objects.select_related().filter( record=record, type=docschema) ] return render_template('carenets', { 'carenets': carenets, 'record': record }, type="xml")
def document_list(request, limit, offset, status, order_by='created_at', record=None, pha=None): """ As of 2010-08-16, type is no longer part of the URL, it's only in the GET query parameters """ # SZ: CLEAN CODE! # SZ: CLEAN CODE! # SZ: CLEAN CODE! type = request.GET.get('type', None) type = DocumentProcessing.expand_schema(type) try: if type: try: type_obj = DocumentSchema.objects.get(type=type) if record: docs = record.documents.filter(type=type_obj, replaced_by=None, status=status, pha=pha).order_by(order_by) else: docs = Document.objects.filter(type=type_obj, pha=pha, replaced_by=None, status=status).order_by(order_by) return _render_documents(docs, record, pha, docs.count()) except DocumentSchema.DoesNotExist: raise Http404 docs = Document.objects.filter(record=record, replaced_by=None, pha=pha, status=status).order_by(order_by) except: docs = [] return _render_documents(docs[offset:offset+limit], record, pha, len(docs))
def _setupargs(self, attachment_num=1, message=None, content='<?xml version="1.0" ?><body></body>', size=None, type=None): self.message = message self.attachment_num = attachment_num self.content = content self.size = size or len(content) self.type = type or DocumentProcessing(content, 'application/xml').xml_type
def replace(self, new_content, new_mime_type): """ Replace the content of the current document with new content and mime_type """ if self.replaced_by: raise ValueError( "cannot replace a document that is already replaced") from indivo.document_processing.document_processing import DocumentProcessing new_doc = DocumentProcessing(new_content, new_mime_type) if not new_doc.is_binary: # set content and mime_type self.content = new_doc.content self.mime_type = new_mime_type # empty out derived fields so that doc processing will repopulate them self.type = None self.size = None self.digest = None else: # Why aren't we doing anything for binaries? pass self.processed = False # We have changed the content, which now needs processing self.save() return True
def document_list(request, limit, offset, status, order_by='created_at', record=None, pha=None): """ List Indivo documents. **Arguments:** * *request*: The incoming Django HttpRequest object. ``request.GET`` may contain: * *type*: The Indivo document schema type on which to filter the resut set. As of 2010-08-16, type is no longer part of the URL, it's only in the GET query parameters. * *limit*, *offset*, *status*, *order_by*: Standard paging and filtering arguments. See :py:func:`~indivo.lib.view_decorators.marsloader` or :doc:`/query-api`. * *record*: if desired documents are record-specific, this :py:class:`~indivo.models.records_and_documents.Record` instance refers to the record to filter on. * *pha*: if the desired documents are application-specific, this :py:class:`~indivo.models.apps.PHA` instance refers to the app to filter on. **Returns:** * an HTTPResponse whose body is an XML string containing the rendered list of documents (which might be empty), on success. **Raises:** * :py:exc:`django.http.Http404`: if *type* was passed, but didn't correspond to an existing Indivo schema. """ # SZ: CLEAN CODE! # SZ: CLEAN CODE! # SZ: CLEAN CODE! type = request.GET.get('type', None) type = DocumentProcessing.expand_schema(type) try: if type: try: type_obj = DocumentSchema.objects.get(type=type) if record: docs = record.documents.filter(type=type_obj, replaced_by=None, status=status, pha=pha).order_by(order_by) else: docs = Document.objects.filter(type=type_obj, pha=pha, replaced_by=None, status=status).order_by(order_by) return _render_documents(docs, record, pha, docs.count()) except DocumentSchema.DoesNotExist: raise Http404 docs = Document.objects.filter(record=record, replaced_by=None, pha=pha, status=status).order_by(order_by) except: docs = [] return _render_documents(docs[offset:offset+limit], record, pha, len(docs))
def document_list(request, query_options, record=None, pha=None): """ List Indivo documents. **Arguments:** * *request*: The incoming Django HttpRequest object. ``request.GET`` may contain: * *type*: The Indivo document schema type on which to filter the resut set. As of 2010-08-16, type is no longer part of the URL, it's only in the GET query parameters. * *limit*, *offset*, *status*, *order_by*: Standard paging and filtering arguments. See :py:func:`~indivo.lib.view_decorators.marsloader` or :doc:`/query-api`. * *record*: if desired documents are record-specific, this :py:class:`~indivo.models.records_and_documents.Record` instance refers to the record to filter on. * *pha*: if the desired documents are application-specific, this :py:class:`~indivo.models.apps.PHA` instance refers to the app to filter on. **Returns:** * an HTTPResponse whose body is an XML string containing the rendered list of documents (which might be empty), on success. **Raises:** * :py:exc:`django.http.Http404`: if *type* was passed, but didn't correspond to an existing Indivo schema. """ order_by = query_options['order_by'] offset = query_options['offset'] limit = query_options['limit'] status = query_options['status'] fqn = DocumentProcessing.expand_schema(request.GET.get('type', None)) try: if fqn: try: if record: docs = record.documents.filter(fqn=fqn, replaced_by=None, status=status, pha=pha).order_by(order_by) else: docs = Document.objects.filter(fqn=fqn, pha=pha, replaced_by=None, status=status).order_by(order_by) return _render_documents(docs, record, pha, docs.count()) except DocumentSchema.DoesNotExist: raise Http404 docs = Document.objects.filter(record=record, replaced_by=None, pha=pha, status=status).order_by(order_by) except: docs = [] return _render_documents(docs[offset:offset+limit], record, pha, len(docs))
def replace(self, new_content, new_mime_type): """ Replace the content of the current document with new content and mime_type """ if self.replaced_by: raise Exception("cannot replace a document that is already replaced") from indivo.document_processing.document_processing import DocumentProcessing new_doc = DocumentProcessing(new_content, new_mime_type) if not new_doc.is_binary: self.type = new_doc.get_document_schema() self.digest = new_doc.get_document_digest() self.size = new_doc.get_document_size() self.content = new_doc.content else: # Why aren't we doing anything for binaries? pass self.save() return True
def autoshare_delete(request, record, carenet): TYPE = 'type' if request.POST.has_key(TYPE): try: docschema = DocumentSchema.objects.get(type = DocumentProcessing.expand_schema(request.POST[TYPE])) except DocumentSchema.DoesNotExist: raise Http404 CarenetAutoshare.objects.filter(record = record, carenet = carenet, type = docschema).delete() return DONE
def replace(self, new_content, new_mime_type): """ Replace the content of the current document with new content and mime_type """ if self.replaced_by: raise Exception( "cannot replace a document that is already replaced") from indivo.document_processing.document_processing import DocumentProcessing new_doc = DocumentProcessing(new_content, new_mime_type) if not new_doc.is_binary: self.type = new_doc.get_document_schema() self.digest = new_doc.get_document_digest() self.size = new_doc.get_document_size() self.content = new_doc.content else: # Why aren't we doing anything for binaries? pass self.save() return True
def add_attachment(self, attachment_num, content): """ attachment_num is 1-indexed """ if int(attachment_num) > self.num_attachments: raise Exception("attachment num is too high") mime_type = 'application/xml' # Only handle XML attachments for now from indivo.document_processing.document_processing import DocumentProcessing doc_utils = DocumentProcessing(content, mime_type) attachment = MessageAttachment.objects.create( message=self, content=content, size=doc_utils.get_document_size(), type=doc_utils.get_type(), attachment_num=attachment_num) return attachment
def add_attachment(self, attachment_num, content): """ attachment_num is 1-indexed """ if int(attachment_num) > self.num_attachments: raise Exception("attachment num is too high") mime_type='application/xml' # Only handle XML attachments for now from indivo.document_processing.document_processing import DocumentProcessing doc_utils = DocumentProcessing(content, mime_type) attachment = MessageAttachment.objects.create( message = self, content = content, size = doc_utils.get_document_size(), type = doc_utils.get_type(), attachment_num = attachment_num) return attachment
def autoshare_list(request, record): TYPE = 'type' autoshares = [] if request.GET.has_key(TYPE): try: docschema = DocumentSchema.objects.get(type = DocumentProcessing.expand_schema(request.GET[TYPE])) except DocumentSchema.DoesNotExist: raise Http404 carenets = [autoshare.carenet for autoshare in CarenetAutoshare.objects.select_related().filter( record = record, type = docschema)] return render_template('carenets', { 'carenets' : carenets, 'record' : record}, type="xml")
def save(self, *args, **kwargs): """ Handle document processing whenever a new document is created. This method processes the document, updates fact objects, and then saves the document """ fobjs_to_update = [] if not self.processed: # import dynamically because DocumentProcessing imports DocumentSchema from this file from indivo.document_processing.document_processing import DocumentProcessing doc = DocumentProcessing(self.content, self.mime_type) # Process the Doc, if necessary if not self.pha and self.content: doc.process() # Update fact docs as Necessary if hasattr(doc, 'f_objs'): for fobj in doc.f_objs: # Delete fact objects from the document we are replacing if self.replaces: fobj.__class__.objects.filter( document=self.replaces).delete() # we can't update here, since we don't have an id yet if fobj: fobjs_to_update.append(fobj) # Update document info based on processing if doc.is_binary: self.content = None self.type = self.type if self.type else doc.get_document_schema() self.size = self.size if self.size else doc.get_document_size() self.digest = self.digest if self.digest else doc.get_document_digest( ) # Mark document as processed self.processed = True super(Document, self).save(*args, **kwargs) # Update newly created Fact objs, if any for fobj in fobjs_to_update: fobj.document = self fobj.record = self.record fobj.save() if not self.original: self.original = self self.save()
def _process_doc(content, pha): """process the document into medical facts. exceptions are passed up without processing.""" if content: doc = DocumentProcessing(content) doc.is_binary = DocumentUtils().is_binary(content) if not pha: doc.process() doc.get_document_schema() return doc return False
def document_list(request, limit, offset, status, order_by='created_at', record=None, pha=None): """ As of 2010-08-16, type is no longer part of the URL, it's only in the GET query parameters """ # SZ: CLEAN CODE! # SZ: CLEAN CODE! # SZ: CLEAN CODE! type = request.GET.get('type', None) type = DocumentProcessing.expand_schema(type) try: if type: try: type_obj = DocumentSchema.objects.get(type=type) if record: docs = record.documents.filter(type=type_obj, replaced_by=None, status=status, pha=pha).order_by(order_by) else: docs = Document.objects.filter( type=type_obj, pha=pha, replaced_by=None, status=status).order_by(order_by) return _render_documents(docs, record, pha, docs.count()) except DocumentSchema.DoesNotExist: raise Http404 docs = Document.objects.filter(record=record, replaced_by=None, pha=pha, status=status).order_by(order_by) except: docs = [] return _render_documents(docs[offset:offset + limit], record, pha, len(docs))
def save(self, *args, **kwargs): """ Handle document processing whenever a new document is created. This method processes the document, updates fact objects, and then saves the document """ fobjs_to_update = [] if not self.processed: # import dynamically because DocumentProcessing imports DocumentSchema from this file from indivo.document_processing.document_processing import DocumentProcessing doc = DocumentProcessing(self.content, self.mime_type) # Process the Doc, if necessary if not self.pha and self.content: doc.process() # Update fact docs as Necessary if hasattr(doc, 'f_objs'): for fobj in doc.f_objs: # Delete fact objects from the document we are replacing if self.replaces: fobj.__class__.objects.filter(document = self.replaces).delete() # we can't update here, since we don't have an id yet if fobj: fobjs_to_update.append(fobj) # Update document info based on processing if doc.is_binary: self.content = None self.type = self.type if self.type else doc.get_document_schema() self.size = self.size if self.size else doc.get_document_size() self.digest = self.digest if self.digest else doc.get_document_digest() # Mark document as processed self.processed = True super(Document,self).save(*args, **kwargs) # Update newly created Fact objs, if any for fobj in fobjs_to_update: fobj.document = self fobj.record = self.record fobj.save() if not self.original: self.original = self self.save()
def autoshare_create(request, record, carenet): """ Automatically share all documents of a certain type into a carenet. request.POST must contain: * *type*: the document schema namespace to create an autoshare for Will return :http:statuscode:`200` on sucess, :http:statuscode:`404` if the specified *type* doesn't exist. """ TYPE = 'type' if request.POST.has_key(TYPE): try: docschema = DocumentSchema.objects.get(type = DocumentProcessing.expand_schema(request.POST[TYPE])) except DocumentSchema.DoesNotExist: raise Http404 CarenetAutoshare.objects.create(record = record, carenet = carenet, type = docschema) return DONE
def autoshare_create(request, record, carenet): """ Automatically share all documents of a certain type into a carenet. request.POST must contain: * *type*: the document schema namespace to create an autoshare for Will return :http:statuscode:`200` on sucess, :http:statuscode:`404` if the specified *type* doesn't exist. """ TYPE = 'type' if request.POST.has_key(TYPE): try: docschema = DocumentSchema.objects.get( type=DocumentProcessing.expand_schema(request.POST[TYPE])) except DocumentSchema.DoesNotExist: raise Http404 CarenetAutoshare.objects.create(record=record, carenet=carenet, type=docschema) return DONE
def autoshare_list(request, record): """ For a single record, list all carenets that a given doctype is autoshared with. request.GET must contain: * *type*: the document schema namespace to check autoshares for Will return :http:statuscode:`200` with a list of carenets that have an autoshare set up for doctype *type* on success, :http:statuscode:`404` if the specified *type* doesn't exist. """ TYPE = 'type' autoshares = [] if request.GET.has_key(TYPE): try: docschema = DocumentSchema.objects.get(type = DocumentProcessing.expand_schema(request.GET[TYPE])) except DocumentSchema.DoesNotExist: raise Http404 carenets = [autoshare.carenet for autoshare in CarenetAutoshare.objects.select_related().filter( record = record, type = docschema)] return render_template('carenets', { 'carenets' : carenets, 'record' : record}, type="xml")
def save(self, *args, **kwargs): """ Handle document processing whenever a new document is created. This method processes the document, updates fact objects, and then saves the document """ if self.processed: doc = None # Nothing to do here else: # import dynamically because DocumentProcessing imports DocumentSchema from this file from indivo.document_processing.document_processing import DocumentProcessing doc = DocumentProcessing(self.content, self.mime_type) # Process the Doc, if necessary if not self.pha and self.content: doc.process() # Delete fact objects from the document we are replacing if self.replaces: from indivo.models import Fact Fact.objects.filter(document = self.replaces).delete() # Update document info based on processing self.type = self.type if self.type else doc.get_document_schema() self.size = self.size if self.size else doc.get_document_size() self.digest = self.digest if self.digest else doc.get_document_digest() # Create our content file if we are binary cf = None if doc.is_binary: cf = ContentFile(self.content) self.content = None # Oracle is incompatible with multi-column unique constraints where # one column might be null (i.e., UNIQUE(record, external_id)). # We therefore insure that all Documents have an external id, # mirroring the internal id if none was passed in. # Set the external_id to a random uuid so that we can save it to the # db before it has an internal id if not self.external_id: self.external_id = 'TEMP-EXTID' + str(uuid.uuid4()) super(Document,self).save(*args, **kwargs) # Will we need to rewrite this to the DB after changes? save_again = False # Now that we have an id, we can handle any document-processing stuff that requires an id if not self.processed: # save our content file if we were binary, now that we have an id. if cf: self.content_file.save(self.id, cf, save=False) # Don't force a save now, as we will resave later # We can also mark the document we are replacing as replaced by us if self.replaces: self.replaces.replaced_by = self self.replaces.save() # Mark document as processed self.processed = True save_again = True # If we set a temporary external_id, set it to mirror the internal id if self.external_id.startswith('TEMP-EXTID'): self.external_id = self.id save_again = True # Update newly created Fact objs, if we created any if doc and hasattr(doc, 'f_objs'): for fobj in doc.f_objs: if fobj: fobj.document = self fobj.record = self.record fobj.save() if not self.original: self.original = self save_again = True if save_again: self.save()
def save(self, *args, **kwargs): """ Handle document processing whenever a new document is created. This method processes the document, updates fact objects, and then saves the document """ if self.processed: doc = None # Nothing to do here else: # import dynamically because DocumentProcessing imports DocumentSchema from this file from indivo.document_processing.document_processing import DocumentProcessing doc = DocumentProcessing(self.content, self.mime_type) # Process the Doc, if necessary if not self.pha and self.content: doc.process() # Delete fact objects from the document we are replacing if self.replaces: from indivo.models import Fact Fact.objects.filter(document=self.replaces).delete() # Update document info based on processing self.type = self.type if self.type else doc.get_document_schema() self.size = self.size if self.size else doc.get_document_size() self.digest = self.digest if self.digest else doc.get_document_digest( ) # Create our content file if we are binary cf = None if doc.is_binary: self.content = None cf = ContentFile(self.content) # Oracle is incompatible with multi-column unique constraints where # one column might be null (i.e., UNIQUE(record, external_id)). # We therefore insure that all Documents have an external id, # mirroring the internal id if none was passed in. # Set the external_id to a random uuid so that we can save it to the # db before it has an internal id if not self.external_id: self.external_id = 'TEMP-EXTID' + str(uuid.uuid4()) super(Document, self).save(*args, **kwargs) # Will we need to rewrite this to the DB after changes? save_again = False # Now that we have an id, we can handle any document-processing stuff that requires an id if not self.processed: # save our content file if we were binary, now that we have an id. if cf: self.content_file.save( self.id, cf, save=False ) # Don't force a save now, as we will resave later # We can also mark the document we are replacing as replaced by us if self.replaces: self.replaces.replaced_by = self self.replaces.save() # Mark document as processed self.processed = True save_again = True # If we set a temporary external_id, set it to mirror the internal id if self.external_id.startswith('TEMP-EXTID'): self.external_id = self.id save_again = True # Update newly created Fact objs, if we created any if doc and hasattr(doc, 'f_objs'): for fobj in doc.f_objs: if fobj: fobj.document = self fobj.record = self.record fobj.save() if not self.original: self.original = self save_again = True if save_again: self.save()
def save(self, *args, **kwargs): """ Handle document processing whenever a new document is created. This method processes the document, updates fact objects, and then saves the document """ fobjs_to_update = [] if not self.processed: # import dynamically because DocumentProcessing imports DocumentSchema from this file from indivo.document_processing.document_processing import DocumentProcessing doc = DocumentProcessing(self.content, self.mime_type) # Process the Doc, if necessary if not self.pha and self.content: doc.process() # Update fact docs as Necessary if hasattr(doc, 'f_objs'): for fobj in doc.f_objs: # Delete fact objects from the document we are replacing if self.replaces: fobj.__class__.objects.filter(document = self.replaces).delete() # we can't update here, since we don't have an id yet if fobj: fobjs_to_update.append(fobj) # Update document info based on processing if doc.is_binary: self.content = None self.type = self.type if self.type else doc.get_document_schema() self.size = self.size if self.size else doc.get_document_size() self.digest = self.digest if self.digest else doc.get_document_digest() # Mark document as processed self.processed = True # Oracle is incompatible with multi-column unique constraints where # one column might be null (i.e., UNIQUE(record, external_id)). # We therefore insure that all Documents have an external id, # mirroring the internal id if none was passed in. # Set the external_id to a random uuid so that we can save it to the # db before it has an internal id if not self.external_id: self.external_id = 'TEMP-EXTID' + str(uuid.uuid4()) super(Document,self).save(*args, **kwargs) # Do we need to rewrite this to the DB after changes? save_again = False # If we set a temporary external_id, set it to mirror the internal id if self.external_id.startswith('TEMP-EXTID'): self.external_id = self.id save_again = True # Update newly created Fact objs, if any for fobj in fobjs_to_update: fobj.document = self fobj.record = self.record fobj.save() if not self.original: self.original = self save_again = True if save_again: self.save()
def _document_create(creator, content, pha, record, replaces_document=None, external_id=None, mime_type=None, status=None): """ Create an Indivo Document This is called for both document creation within a record and document creation within a record for a specific application. The PHA argument, if non-null, indicates app-specificity only. By this point, the external_id should be fully formed. FIXME: figure out the transactional aspect here If status is specified, then it is used, otherwise it is not specified and the DB does its default thing. """ new_doc = None # Overwrite content if we are replacing an existing PHA doc if pha and replaces_document: replaces_document.replace(content, mime_type) # Create new document else: creator = creator.effective_principal doc_args = { PHA: pha, RECORD: record, CREATOR: creator, MIME_TYPE: mime_type, EXTERNAL_ID: external_id, REPLACES: replaces_document, CONTENT: content, ORIGINAL_ID: replaces_document.original_id if replaces_document else None } if status: create_args[STATUS] = status # create the document new_doc = Document.objects.create(**doc_args) # Save the binary file if DocumentProcessing(content, mime_type).is_binary: file = ContentFile(content) new_doc.content_file.save(new_doc.id, file) # Mark old doc as replaced if replaces_document: replaces_document.replaced_by = new_doc replaces_document.save() # return new doc if we have it, otherwise updated old doc return new_doc or replaces_document