Exemple #1
0
    def audit(self, auditor: Auditor) -> None:
        """Audit and repair BLOCKS section.

        .. important::

            Do not delete entities while auditing process, because this
            would alter the entity database while iterating, instead use::

                auditor.trash(entity)

            to delete invalid entities after auditing automatically.

        """
        assert self.doc is auditor.doc, "Auditor for different DXF document."

        for block_record in self.block_records:
            assert isinstance(block_record, BlockRecord)
            for entity in block_record.entity_space:
                if not is_graphic_entity(entity):
                    auditor.fixed_error(
                        code=AuditError.REMOVED_INVALID_GRAPHIC_ENTITY,
                        message=f"Removed invalid DXF entity {str(entity)} from"
                        f" BLOCK '{block_record.dxf.name}'.",
                    )
                    auditor.trash(entity)
                elif isinstance(entity, Attrib):
                    # ATTRIB can only exist as an attached entity of the INSERT
                    # entity!
                    auditor.fixed_error(
                        code=AuditError.REMOVED_STANDALONE_ATTRIB_ENTITY,
                        message=f"Removed standalone {str(entity)} entity from"
                        f" BLOCK '{block_record.dxf.name}'.",
                    )
                    auditor.trash(entity)
Exemple #2
0
def read(stream: BinaryIO,
         errors: str = 'surrogateescape') -> Tuple['Drawing', 'Auditor']:
    """ Read a DXF document from a binary-stream similar to :func:`ezdxf.read`,
    but this function will detect the text encoding automatically and repair
    as much flaws as possible, runs the required audit process afterwards
    and returns the DXF document and the :class:`Auditor`.

    Args:
        stream: data stream to load in binary read mode
        errors: specify decoding error handler

            - "surrogateescape" to preserve possible binary data (default)
            - "ignore" to use the replacement char U+FFFD "\ufffd" for invalid data
            - "strict" to raise an :class:`UnicodeDecodeError` exception for invalid data

    Raises:
        DXFStructureError: for invalid or corrupted DXF structures
        UnicodeDecodeError: if `errors` is "strict" and a decoding error occurs

    """
    from ezdxf.document import Drawing
    recover_tool = Recover.run(stream, errors=errors)
    doc = Drawing()
    doc._load_section_dict(recover_tool.section_dict)

    auditor = Auditor(doc)
    for code, msg in recover_tool.errors:
        auditor.add_error(code, msg)
    for code, msg in recover_tool.fixes:
        auditor.fixed_error(code, msg)
    auditor.run()
    return doc, auditor
Exemple #3
0
def _load_and_audit_document(recover_tool) -> Tuple['Drawing', 'Auditor']:
    from ezdxf.document import Drawing

    doc = Drawing()
    doc._load_section_dict(recover_tool.section_dict)

    auditor = Auditor(doc)
    for code, msg in recover_tool.errors:
        auditor.add_error(code, msg)
    for code, msg in recover_tool.fixes:
        auditor.fixed_error(code, msg)
    auditor.run()
    return doc, auditor
Exemple #4
0
 def _fix_entry_handles(self, auditor: Auditor):
     # Why: see duplicate handle issue #604
     entitydb = self.entitydb
     for entry in self:
         entity = entitydb.get(entry.dxf.handle)
         if entity is not entry:  # duplicate handle usage
             # This can break entities referring to this entity, but at
             # least the DXF readable
             entry.dxf.handle = entitydb.next_handle()
             self.entitydb.add(entry)
             auditor.fixed_error(
                 code=AuditError.INVALID_TABLE_HANDLE,
                 message=f"Fixed invalid table entry handle in {entry}",
             )
Exemple #5
0
    def audit(self, auditor: Auditor) -> None:
        """Audit and repair OBJECTS section.

        .. important::

            Do not delete entities while auditing process, because this
            would alter the entity database while iterating, instead use::

                auditor.trash(entity)

            to delete invalid entities after auditing automatically.

        """
        assert self.doc is auditor.doc, "Auditor for different DXF document."
        for entity in self._entity_space:
            if not is_dxf_object(entity):
                auditor.fixed_error(
                    code=AuditError.REMOVED_INVALID_DXF_OBJECT,
                    message=f"Removed invalid DXF entity {str(entity)} "
                    f"from OBJECTS section.",
                )
                auditor.trash(entity)