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.

126 lines
4.1 KiB

  1. # Copyright 2020 Coop IT Easy SCRL fs
  2. # Robin Keunen <robin@coopiteasy.be>
  3. # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
  4. import json
  5. import logging
  6. import requests
  7. from werkzeug.exceptions import BadRequest, InternalServerError, NotFound
  8. from odoo import _, api, fields, models
  9. from odoo.exceptions import AccessDenied, Warning as UserError
  10. _logger = logging.getLogger(__name__)
  11. class EMCBackend(models.Model):
  12. _name = "emc.backend"
  13. _description = "EMC Backend"
  14. name = fields.Char(string="Name", required=True)
  15. location = fields.Char(string="URL")
  16. api_key = fields.Char(string="API Key")
  17. description = fields.Text(string="Description", required=False)
  18. active = fields.Boolean(string="active", default=True)
  19. @api.model
  20. def get_backend(self):
  21. backend = self.env["emc.backend"].search([("active", "=", True)])
  22. try:
  23. backend.ensure_one()
  24. except ValueError as e:
  25. _logger.error(
  26. "One and only one backend is allowed for the Easy My Coop "
  27. "connector."
  28. )
  29. raise e
  30. return backend
  31. @api.multi
  32. def http_get(self, url, params=None, headers=None):
  33. self.ensure_one()
  34. headers = self._add_api_key(headers)
  35. if url.startswith("/"):
  36. url = self.location + url
  37. _logger.info("GET to {} w/ params {}".format(url, params))
  38. return requests.get(url, params=params, headers=headers)
  39. def _process_response(self, response):
  40. if response.status_code == 200:
  41. content = response.content.decode("utf-8")
  42. return json.loads(content)
  43. elif response.status_code == 400:
  44. content = response.content.decode("utf-8")
  45. raise BadRequest(
  46. _(
  47. "request returned status code %s with message %s"
  48. % (response.status_code, content)
  49. )
  50. )
  51. elif response.status_code == 403:
  52. raise AccessDenied(
  53. _("You are not allowed to access this resource")
  54. )
  55. elif response.status_code == 404:
  56. raise NotFound(
  57. _("Resource not found %s on server" % response.status_code)
  58. )
  59. else: # 500 et al.
  60. content = response.content.decode("utf-8")
  61. raise InternalServerError(
  62. _(
  63. "request returned status code %s with message %s"
  64. % (response.status_code, content)
  65. )
  66. )
  67. @api.multi
  68. def http_get_content(self, url, params=None, headers=None):
  69. self.ensure_one()
  70. response = self.http_get(url, params=params, headers=headers)
  71. return self._process_response(response)
  72. @api.multi
  73. def http_post(self, url, data, headers=None):
  74. self.ensure_one()
  75. headers = self._add_api_key(headers)
  76. if url.startswith("/"):
  77. url = self.location + url
  78. _logger.info("POST to %s %s" % url)
  79. return requests.post(url, json=data, headers=headers)
  80. def http_post_content(self, url, data, headers=None):
  81. self.ensure_one()
  82. response = self.http_post(url, data, headers=headers)
  83. return self._process_response(response)
  84. @api.multi
  85. def _add_api_key(self, headers):
  86. self.ensure_one()
  87. key_dict = {"API-KEY": self.api_key}
  88. if headers:
  89. headers.update(key_dict)
  90. else:
  91. headers = key_dict
  92. return headers
  93. @api.multi
  94. def action_ping(self):
  95. self.ensure_one()
  96. url = self.location + "/api/ping/test"
  97. try:
  98. response = requests.get(url)
  99. except Exception as e:
  100. _logger.error(e)
  101. raise UserError(_("Failed to connect to backend: %s" % str(e)))
  102. if response.status_code == 200:
  103. content = json.loads(response.content.decode("utf-8"))
  104. raise UserError(_("Success: %s") % content["message"])
  105. else:
  106. raise UserError(
  107. _("Failed to connect to backend: %s" % str(response.content))
  108. )