No Description
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.0KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  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. 'internal': bool,
  37. 'string': MlString.load,
  38. 'help_text': MlString.load,
  39. 'date_create': date_cast,
  40. 'date_update': date_cast,
  41. }
  42. ## Constructor
  43. #
  44. # @param json_file str: path to the json_file used as data source
  45. # @param json_string str: json_data used as data source
  46. def __init__(self, json_file=None, json_string=None):
  47. if (not json_file and not json_string) or (json_file and json_string):
  48. raise AttributeError
  49. self._json_file = json_file
  50. self._json_string = json_string
  51. @staticmethod
  52. ## @brief Used by json.dumps to serialize date and datetime
  53. def date_handler(obj):
  54. return obj.strftime('%c') if isinstance(obj, datetime.datetime) or isinstance(obj, datetime.date) else None
  55. ## Loads the data from given file or string
  56. #
  57. # @return list
  58. def load(self):
  59. data = {}
  60. json_string = self._load_from_file() if self._json_file else self._json_string
  61. json_data = json.loads(json_string)
  62. for index, component in json_data.items():
  63. attributes = {}
  64. for attr_name, attr_value in component.items():
  65. if attr_name in EmBackendJson.cast_methods:
  66. attributes[attr_name] = EmBackendJson.cast_methods[attr_name](attr_value)
  67. else:
  68. attributes[attr_name] = attr_value
  69. data[int(index)] = attributes
  70. return data
  71. def _load_from_file(self):
  72. with open(self._json_file) as content:
  73. data = content.read()
  74. return data
  75. ## Saves the data in the data source json file
  76. # @param filename str : The filename to save the EM in (if None use self.json_file provided at init )
  77. def save(self, model, filename=None):
  78. json_dump = json.dumps({component.uid: component.attr_flat() for component in model.components()}, default=self.date_handler)
  79. if self._json_file:
  80. with open(self._json_file if filename is None else filename, 'w') as json_file:
  81. json_file.write(json_dump)
  82. else:
  83. return json_dump