filemanagement.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. # Purpose: DXF file testing and opening
  2. # Created: 05.01.2018
  3. # Copyright (C) 2018, Manfred Moitzi
  4. # License: MIT License
  5. # Local imports to avoid cyclic import
  6. from typing import TextIO, TYPE_CHECKING, Union, Sequence
  7. from ezdxf.tools.standards import setup_drawing
  8. if TYPE_CHECKING:
  9. from ezdxf.eztypes import Drawing, DXFInfo
  10. def new(dxfversion: str = 'AC1009', setup: Union[str, bool, Sequence[str]] = None) -> 'Drawing':
  11. """
  12. Create a new DXF drawing.
  13. new() can create drawings for following DXF versions:
  14. - AC1009 or R12: AutoCAD R12 (DXF R12)
  15. - AC1015 or R2000: AutoCAD 2000 (DXF R2000)
  16. - AC1018 or R2004: AutoCAD 2004 (DXF R2004)
  17. - AC1021 or R2007: AutoCAD 2007 (DXF R2007)
  18. - AC1024 or R2010: AutoCAD 2010 (DXF R2010)
  19. - AC1027 or R2013: AutoCAD 2013 (DXF R2013)
  20. - AC1032 or R2018: AutoCAD 2018 (DXF R2018)
  21. Args:
  22. dxfversion: DXF version specifier, default is AC1009
  23. setup: setup drawing standard for linetypes, text styles, dimension styles
  24. None or False: no setup
  25. 'all' or True: setup all
  26. list of topics as strings:
  27. - 'linetypes' ... setup line types
  28. - 'styles' ... setup text styles
  29. - 'dimstyles ... setup all dimension styles
  30. - 'dimstyles:metric' ... setup metric dimension styles
  31. - 'dimstyles:imperial' ... setup imperial dimension styles (not implemented yet)
  32. """
  33. from ezdxf.drawing import Drawing
  34. dwg = Drawing.new(dxfversion)
  35. if dwg.dxfversion > 'AC1009':
  36. dwg.reset_fingerprintguid()
  37. dwg.reset_versionguid()
  38. if setup:
  39. setup_drawing(dwg, topics=setup)
  40. return dwg
  41. def read(stream: TextIO, legacy_mode: bool = True, dxfversion: str = None) -> 'Drawing':
  42. """
  43. Read DXF drawing from a text stream, which only needs a readline() method.
  44. Supported DXF versions:
  45. - pre AC1009 DXF versions will be upgraded to AC1009, requires encoding set by header var $DWGCODEPAGE
  46. - AC1009: AutoCAD R12 (DXF R12), requires encoding set by header var $DWGCODEPAGE
  47. - AC1012: AutoCAD R13 upgraded to AC1015, requires encoding set by header var $DWGCODEPAGE
  48. - AC1014: AutoCAD R14 upgraded to AC1015, requires encoding set by header var $DWGCODEPAGE
  49. - AC1015: AutoCAD 2000, requires encoding set by header var $DWGCODEPAGE
  50. - AC1018: AutoCAD 2004, requires encoding set by header var $DWGCODEPAGE
  51. - AC1021: AutoCAD 2007, requires encoding='utf-8'
  52. - AC1024: AutoCAD 2010, requires encoding='utf-8'
  53. - AC1027: AutoCAD 2013, requires encoding='utf-8'
  54. - AC1032: AutoCAD 2018, requires encoding='utf-8'
  55. To detect the required encoding, use the helper function info=dxf_stream_info(stream)
  56. and reopen the stream with the detected info.encoding.
  57. Args:
  58. stream: input text stream opened with correct encoding, requires only a readline() method.
  59. legacy_mode: True - adds an extra trouble shooting import layer; False - requires DXF file from modern CAD apps
  60. dxfversion: DXF version, None = auto detect, just important for legacy mode.
  61. """
  62. from ezdxf.drawing import Drawing
  63. return Drawing.read(stream, legacy_mode=legacy_mode, dxfversion=dxfversion)
  64. def dxf_file_info(filename: str) -> 'DXFInfo':
  65. """
  66. Reads basic file information from DXF files: DXF version, encoding and handle seed.
  67. Returns:
  68. DXF info object with attributes: version, release, handseed, encoding
  69. """
  70. with open(filename, mode='rt', encoding='utf-8', errors='ignore') as fp:
  71. return dxf_stream_info(fp)
  72. def dxf_stream_info(stream: TextIO) -> 'DXFInfo':
  73. """
  74. Reads basic DXF information from a text stream: DXF version, encoding and handle seed.
  75. Returns:
  76. DXF info object with attributes: version, release, handseed, encoding
  77. """
  78. from ezdxf.lldxf.tags import dxf_info
  79. info = dxf_info(stream)
  80. if info.version >= 'AC1021': # R2007 files and later are always encoded as UTF-8
  81. info.encoding = 'utf-8'
  82. return info
  83. def readfile(filename: str, encoding: str = None, legacy_mode: bool = False) -> 'Drawing':
  84. """
  85. Read DXF drawing specified by *filename* from file system.
  86. Supported DXF versions:
  87. - pre AC1009 DXF versions will be upgraded to AC1009
  88. - AC1009: AutoCAD R12 (DXF R12)
  89. - AC1012: AutoCAD R13 upgraded to AC1015
  90. - AC1014: AutoCAD R14 upgraded to AC1015
  91. - AC1015: AutoCAD 2000
  92. - AC1018: AutoCAD 2004
  93. - AC1021: AutoCAD 2007, fixates encoding='utf-8'
  94. - AC1024: AutoCAD 2010, fixates encoding='utf-8'
  95. - AC1027: AutoCAD 2013, fixates encoding='utf-8'
  96. - AC1032: AutoCAD 2018, fixates encoding='utf-8'
  97. Args:
  98. filename: DXF filename
  99. encoding: use None for auto detect, or set a specific encoding like 'utf-8'
  100. legacy_mode: True - adds an extra trouble shooting import layer; False - requires DXF file from modern CAD apps
  101. """
  102. from ezdxf.lldxf.validator import is_dxf_file
  103. from ezdxf.tools.codepage import is_supported_encoding
  104. if not is_dxf_file(filename):
  105. raise IOError("File '{}' is not a DXF file.".format(filename))
  106. info = dxf_file_info(filename)
  107. with open(filename, mode='rt', encoding=info.encoding, errors='ignore') as fp:
  108. dwg = read(fp, legacy_mode=legacy_mode, dxfversion=info.version)
  109. dwg.filename = filename
  110. if encoding is not None and is_supported_encoding(encoding):
  111. dwg.encoding = encoding
  112. return dwg
  113. def readzip(zipfile: str, filename: str = None) -> 'Drawing':
  114. """
  115. Read DXF drawing specified by filename from a zip archive, or if filename is None the first DXF file in the zip
  116. archive.
  117. Supported DXF versions:
  118. - pre AC1009 DXF versions will be upgraded to AC1009
  119. - AC1009: AutoCAD R12 (DXF12)
  120. - AC1012: AutoCAD R13 upgraded to AC1015
  121. - AC1014: AutoCAD R14 upgraded to AC1015
  122. - AC1015: AutoCAD 2000
  123. - AC1018: AutoCAD 2004
  124. - AC1021: AutoCAD 2007
  125. - AC1024: AutoCAD 2010
  126. - AC1027: AutoCAD 2013
  127. - AC1032: AutoCAD 2018
  128. Args:
  129. zipfile: name of the zip archive
  130. filename: filename of DXF file, or None to read the first DXF file from the zip archive.
  131. """
  132. from ezdxf.tools.zipmanager import ctxZipReader
  133. with ctxZipReader(zipfile, filename) as zipstream:
  134. dwg = read(zipstream, dxfversion=zipstream.dxfversion)
  135. dwg.filename = zipstream.dxf_file_name
  136. return dwg