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.

98 lines
3.5 KiB

  1. ###################################################################################
  2. #
  3. # Copyright (c) 2017-2019 MuK IT GmbH.
  4. #
  5. # This file is part of MuK Large Objects Field
  6. # (see https://mukit.at).
  7. #
  8. # This program is free software: you can redistribute it and/or modify
  9. # it under the terms of the GNU Lesser General Public License as published by
  10. # the Free Software Foundation, either version 3 of the License, or
  11. # (at your option) any later version.
  12. #
  13. # This program is distributed in the hope that it will be useful,
  14. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. # GNU Lesser General Public License for more details.
  17. #
  18. # You should have received a copy of the GNU Lesser General Public License
  19. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. #
  21. ###################################################################################
  22. import base64
  23. import hashlib
  24. import logging
  25. import tempfile
  26. from odoo import fields
  27. from odoo.tools import human_size
  28. _logger = logging.getLogger(__name__)
  29. class LargeObject(fields.Field):
  30. type = "lobject"
  31. column_type = ("oid", "oid")
  32. _slots = {
  33. "prefetch": False,
  34. "depends_context": ("bin_size", "human_size", "path", "bytes", "stream"),
  35. }
  36. def convert_to_column(self, value, record, values=None, validate=True):
  37. oid = record.with_context({"oid": True})[self.name]
  38. if oid:
  39. record.env.cr._cnx.lobject(oid, "rb").unlink()
  40. if not value:
  41. return None
  42. lobject = record.env.cr._cnx.lobject(0, "wb")
  43. if isinstance(value, bytes):
  44. lobject.write(value)
  45. elif isinstance(value, str):
  46. lobject.write(base64.b64decode(value))
  47. else:
  48. while True:
  49. chunk = value.read(4096)
  50. if not chunk:
  51. break
  52. lobject.write(chunk)
  53. return lobject.oid
  54. def convert_to_cache(self, value, record, validate=True):
  55. if value and isinstance(value, int):
  56. lobject = record.env.cr._cnx.lobject(value, "rb")
  57. if record._context.get("human_size"):
  58. return human_size(lobject.seek(0, 2))
  59. elif record._context.get("bin_size"):
  60. return lobject.seek(0, 2)
  61. elif record._context.get("oid"):
  62. return lobject.oid
  63. elif record._context.get("bytes"):
  64. return lobject.read()
  65. elif record._context.get("stream"):
  66. file = tempfile.TemporaryFile()
  67. while True:
  68. chunk = lobject.read(4096)
  69. if not chunk:
  70. file.seek(0)
  71. return file
  72. file.write(chunk)
  73. elif record._context.get("checksum"):
  74. checksum = hashlib.sha1()
  75. while True:
  76. chunk = lobject.read(4096)
  77. if not chunk:
  78. return checksum.hexdigest()
  79. checksum.update(chunk)
  80. else:
  81. return base64.b64encode(lobject.read())
  82. return None if value is False else value
  83. def convert_to_export(self, value, record):
  84. if value:
  85. lobject = record.env.cr._cnx.lobject(value, "rb")
  86. if record._context.get("export_raw_data"):
  87. return lobject.read()
  88. return base64.b64encode(lobject.read())
  89. return ""