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.

68 lines
3.0 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
  1. ###################################################################################
  2. #
  3. # Copyright (C) 2018 MuK IT GmbH
  4. #
  5. # This program is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU Affero General Public License as
  7. # published by the Free Software Foundation, either version 3 of the
  8. # License, or (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU Affero General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU Affero General Public License
  16. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. #
  18. ###################################################################################
  19. import logging
  20. import mimetypes
  21. from odoo import models
  22. from odoo.http import request, STATIC_CACHE
  23. from odoo.exceptions import AccessError
  24. _logger = logging.getLogger(__name__)
  25. class LargeObjectControllerIrHttp(models.AbstractModel):
  26. _inherit = 'ir.http'
  27. @classmethod
  28. def lobject_content(cls, xmlid=None, model=None, id=None, field='content', unique=False,
  29. filename=None, filename_field='content_fname', download=False, mimetype=None,
  30. default_mimetype='application/octet-stream', access_token=None, env=None):
  31. obj = None
  32. env = env or request.env
  33. if xmlid:
  34. obj = env.ref(xmlid, False)
  35. elif id and model in env.registry:
  36. obj = env[model].browse(int(id))
  37. if not obj or not obj.exists() or field not in obj:
  38. return (404, [], None)
  39. try:
  40. last_update = obj['__last_update']
  41. except AccessError:
  42. return (403, [], None)
  43. status, headers, content = None, [], None
  44. content = obj.with_context({'stream': True})[field] or b''
  45. if not filename:
  46. if filename_field in obj:
  47. filename = obj[filename_field]
  48. else:
  49. filename = "%s-%s-%s" % (obj._name, obj.id, field)
  50. mimetype = 'mimetype' in obj and obj.mimetype or False
  51. if not mimetype and filename:
  52. mimetype = mimetypes.guess_type(filename)[0]
  53. if not mimetype:
  54. mimetype = default_mimetype
  55. headers += [('Content-Type', mimetype), ('X-Content-Type-Options', 'nosniff')]
  56. etag = bool(request) and request.httprequest.headers.get('If-None-Match')
  57. retag = '"%s"' % obj.with_context({'checksum': True})[field] if content else ""
  58. status = status or (304 if etag == retag else 200)
  59. headers.append(('ETag', retag))
  60. headers.append(('Cache-Control', 'max-age=%s' % (STATIC_CACHE if unique else 0)))
  61. if download:
  62. headers.append(('Content-Disposition', cls.content_disposition(filename)))
  63. return (status, headers, content)