Нема описа
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

json_backend.py 3.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. # -*- coding: utf-8 -*-
  2. ## @package EditorialModel.backend.json_backend
  3. # @brief Handle json files
  4. #
  5. # Allows an editorial model to be loaded/saved in
  6. # json format
  7. import json
  8. import datetime
  9. from Lodel.utils.mlstring import MlString
  10. from EditorialModel.backend.dummy_backend import EmBackendDummy
  11. def date_cast(date):
  12. if len(date):
  13. return datetime.datetime.strptime(date, '%c')
  14. else:
  15. return None
  16. ## @brief dirty obsolote cast function
  17. def int_or_none(i):
  18. if isinstance(i, int):
  19. return i
  20. elif i is None:
  21. return None
  22. elif len(i):
  23. return int(i)
  24. else:
  25. return None
  26. ## Manages a Json file based backend structure
  27. class EmBackendJson(EmBackendDummy):
  28. cast_methods = {
  29. 'uid': int,
  30. 'rank': int,
  31. 'class_id': int,
  32. 'fieldgroup_id': int,
  33. 'rel_to_type_id': int_or_none,
  34. 'rel_field_id': int_or_none,
  35. 'optional': bool,
  36. 'string': MlString.load,
  37. 'help_text': MlString.load,
  38. 'date_create': date_cast,
  39. 'date_update': date_cast,
  40. }
  41. ## Constructor
  42. #
  43. # @param json_file str: path to the json_file used as data source
  44. # @param json_string str: json_data used as data source
  45. def __init__(self, json_file=None, json_string=None):
  46. if (not json_file and not json_string) or (json_file and json_string):
  47. raise AttributeError
  48. self._json_file = json_file
  49. self._json_string = json_string
  50. @staticmethod
  51. ## @brief Used by json.dumps to serialize date and datetime
  52. def date_handler(obj):
  53. return obj.strftime('%c') if isinstance(obj, datetime.datetime) or isinstance(obj, datetime.date) else None
  54. ## Loads the data from given file or string
  55. #
  56. # @return list
  57. def load(self):
  58. data = {}
  59. json_string = self._load_from_file() if self._json_file else self._json_string
  60. json_data = json.loads(json_string)
  61. for index, component in json_data.items():
  62. attributes = {}
  63. for attr_name, attr_value in component.items():
  64. if attr_name in EmBackendJson.cast_methods:
  65. attributes[attr_name] = EmBackendJson.cast_methods[attr_name](attr_value)
  66. else:
  67. attributes[attr_name] = attr_value
  68. data[int(index)] = attributes
  69. return data
  70. def _load_from_file(self):
  71. with open(self._json_file) as content:
  72. data = content.read()
  73. return data
  74. ## Saves the data in the data source json file
  75. # @param model Model : The editorial model
  76. # @param filename str|None : The filename to save the EM in (if None use self.json_file provided at init )
  77. # @return json string
  78. def save(self, model, filename=None):
  79. json_dump = json.dumps({component.uid: component.attr_flat() for component in model.components()}, default=self.date_handler, indent=True)
  80. if self._json_file:
  81. with open(self._json_file if filename is None else filename, 'w') as json_file:
  82. json_file.write(json_dump)
  83. else:
  84. return json_dump