py2txt.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. #
  2. # Metrix++, Copyright 2009-2019, Metrix++ Project
  3. # Link: https://github.com/metrixplusplus/metrixplusplus
  4. #
  5. # This file is a part of Metrix++ Tool.
  6. #
  7. # Copied from http://code.activestate.com/recipes/577268-python-data-structure-to-TXT-serialization/ and modified
  8. '''
  9. Py2TXT - Python to TXT serialization
  10. This code transforms a Python data structures into an TXT document
  11. Usage:
  12. serializer = Py2TXT()
  13. txt_string = serializer.parse( python_object )
  14. print python_object
  15. print txt_string
  16. '''
  17. INDENT_SPACE_SYMBOL = ". "
  18. class Py2TXT():
  19. def __init__( self ):
  20. self.data = "" # where we store the processed TXT string
  21. def parse( self, pythonObj, objName=None, indent = 0 ):
  22. '''
  23. processes Python data structure into TXT string
  24. needs objName if pythonObj is a List
  25. '''
  26. if pythonObj == None:
  27. return "\n" + (INDENT_SPACE_SYMBOL * indent) + ""
  28. if isinstance( pythonObj, dict ):
  29. self.data = self._PyDict2TXT( pythonObj, objName, indent = indent + 1 )
  30. elif isinstance( pythonObj, list ):
  31. # we need name for List object
  32. self.data = self._PyList2TXT( pythonObj, objName, indent = indent + 1 )
  33. else:
  34. self.data = "\n" + (INDENT_SPACE_SYMBOL * indent) + "%(n)s: %(o)s" % { 'n':objName, 'o':str( pythonObj ) }
  35. self.data = (INDENT_SPACE_SYMBOL * (indent + 1)) + "-" * 80 + self.data + "\n" + (INDENT_SPACE_SYMBOL * (indent + 1)) + "=" * 80
  36. return self.data
  37. def _PyDict2TXT( self, pyDictObj, objName=None, indent = 0 ):
  38. '''
  39. process Python Dict objects
  40. They can store TXT attributes and/or children
  41. '''
  42. tagStr = "" # TXT string for this level
  43. attributes = {} # attribute key/value pairs
  44. attrStr = "" # attribute string of this level
  45. childStr = "" # TXT string of this level's children
  46. for k, v in list(pyDictObj.items()):
  47. if isinstance( v, dict ):
  48. # child tags, with attributes
  49. childStr += self._PyDict2TXT( v, k, indent = indent + 1 )
  50. elif isinstance( v, list ):
  51. # child tags, list of children
  52. childStr += self._PyList2TXT( v, k, indent = indent + 1 )
  53. else:
  54. # tag could have many attributes, let's save until later
  55. attributes.update( { k:v } )
  56. if objName == None:
  57. return childStr
  58. # create TXT string for attributes
  59. attrStr += ""
  60. for k, v in list(attributes.items()):
  61. attrStr += "\n" + (INDENT_SPACE_SYMBOL * (indent + 1)) + "%s=\"%s\"" % ( k, v )
  62. # let's assemble our tag string
  63. if childStr == "":
  64. tagStr += "\n" + (INDENT_SPACE_SYMBOL * indent) + "%(n)s: %(a)s" % { 'n':objName, 'a':attrStr }
  65. else:
  66. tagStr += "\n" + (INDENT_SPACE_SYMBOL * indent) + "%(n)s: %(a)s %(c)s" % { 'n':objName, 'a':attrStr, 'c':childStr }
  67. return tagStr
  68. def _PyList2TXT( self, pyListObj, objName=None, indent = 0 ):
  69. '''
  70. process Python List objects
  71. They have no attributes, just children
  72. Lists only hold Dicts or Strings
  73. '''
  74. tagStr = "" # TXT string for this level
  75. childStr = "" # TXT string of children
  76. for childObj in pyListObj:
  77. if isinstance( childObj, dict ):
  78. # here's some Magic
  79. # we're assuming that List parent has a plural name of child:
  80. # eg, persons > person, so cut off last char
  81. # name-wise, only really works for one level, however
  82. # in practice, this is probably ok
  83. childStr += "\n" + (INDENT_SPACE_SYMBOL * indent) + self._PyDict2TXT( childObj, objName[:-1], indent = indent + 1 )
  84. elif isinstance( childObj, list ):
  85. # here's some Magic
  86. # we're assuming that List parent has a plural name of child:
  87. # eg, persons > person, so cut off last char
  88. # name-wise, only really works for one level, however
  89. # in practice, this is probably ok
  90. childStr += self._PyList2TXT( childObj, objName[:-1], indent = indent + 1 )
  91. else:
  92. childStr += "\n" + (INDENT_SPACE_SYMBOL * (indent + 1))
  93. for string in childObj:
  94. childStr += str(string);
  95. if objName == None:
  96. return childStr
  97. tagStr += "\n" + (INDENT_SPACE_SYMBOL * indent) + "%(n)s:%(c)s" % { 'n':objName, 'c':childStr }
  98. return tagStr