sections.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. # Purpose: sections module
  2. # Created: 12.03.2011
  3. # Copyright (c) 2011-2018, Manfred Moitzi
  4. # License: MIT License
  5. from typing import TYPE_CHECKING, Dict, List, Iterable
  6. import logging
  7. from ezdxf.lldxf.const import DXFStructureError
  8. from .header import HeaderSection
  9. from .tables import TablesSection
  10. from .blocks import BlocksSection
  11. from .classes import ClassesSection
  12. from .objects import ObjectsSection
  13. from .entities import EntitySection
  14. from .unsupported import UnsupportedSection
  15. if TYPE_CHECKING:
  16. from ezdxf.eztypes import Drawing, SectionType, TagWriter
  17. logger = logging.getLogger('ezdxf')
  18. KNOWN_SECTIONS = ('HEADER', 'CLASSES', 'TABLES', 'BLOCKS', 'ENTITIES', 'OBJECTS', 'THUMBNAILIMAGE', 'ACDSDATA')
  19. class Sections:
  20. def __init__(self, sections: Dict, drawing: 'Drawing', header: HeaderSection = None):
  21. self._sections = {
  22. 'HEADER': header if header is not None else HeaderSection(tags=None)} # type: Dict[str, SectionType]
  23. self._setup_sections(sections, drawing)
  24. def __iter__(self) -> Iterable['SectionType']:
  25. return iter(self._sections.values())
  26. @staticmethod
  27. def key(name: str) -> str:
  28. return name.upper()
  29. def _setup_sections(self, sections: Dict, drawing: 'Drawing') -> None:
  30. # required sections
  31. self._sections['TABLES'] = TablesSection(sections.get('TABLES', None), drawing)
  32. self._sections['BLOCKS'] = BlocksSection(sections.get('BLOCKS', None), drawing)
  33. self._sections['ENTITIES'] = EntitySection(sections.get('ENTITIES', None), drawing)
  34. if drawing.dxfversion > 'AC1009':
  35. # required sections
  36. self._sections['CLASSES'] = ClassesSection(sections.get('CLASSES', None), drawing)
  37. self._sections['OBJECTS'] = ObjectsSection(sections.get('OBJECTS', None), drawing)
  38. # sections just stored, if exists
  39. if 'THUMBNAILIMAGE' in sections:
  40. self._sections['THUMBNAILIMAGE'] = UnsupportedSection(sections['THUMBNAILIMAGE'], drawing)
  41. if 'ACDSDATA' in sections:
  42. self._sections['ACDSDATA'] = UnsupportedSection(sections['ACDSDATA'], drawing)
  43. for section_name in sections.keys():
  44. if section_name not in KNOWN_SECTIONS:
  45. logging.info('Found unknown SECTION: "{}", removed by ezdxf on saving!'.format(section_name))
  46. def __contains__(self, item: str) -> bool:
  47. return Sections.key(item) in self._sections
  48. def __getattr__(self, key: str) -> 'SectionType':
  49. try:
  50. return self._sections[Sections.key(key)]
  51. except KeyError: # internal exception
  52. # DXFStructureError because a requested section is not present, maybe a typo, but usual a hint for an
  53. # invalid DXF file.
  54. raise DXFStructureError('{} section not found'.format(key.upper()))
  55. def get(self, name: str) -> 'SectionType':
  56. return self._sections.get(Sections.key(name), None)
  57. def names(self) -> List[str]:
  58. return list(self._sections.keys())
  59. def write(self, tagwriter: 'TagWriter') -> None:
  60. write_order = list(KNOWN_SECTIONS)
  61. unknown_sections = frozenset(self._sections.keys()) - frozenset(KNOWN_SECTIONS)
  62. if unknown_sections:
  63. write_order.extend(unknown_sections)
  64. written_sections = []
  65. for section_name in KNOWN_SECTIONS:
  66. section = self._sections.get(section_name, None)
  67. if section is not None:
  68. section.write(tagwriter)
  69. written_sections.append(section.name)
  70. tagwriter.write_tag2(0, 'EOF')
  71. def delete_section(self, name: str) -> None:
  72. """
  73. Delete a complete section, delete only unnecessary sections like 'THUMBNAILIMAGE' or 'ACDSDATA', else the DXF
  74. file is corrupted.
  75. """
  76. del self._sections[Sections.key(name)]