widgets.py 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. from urllib.parse import urlencode
  2. from flask import current_app
  3. from markupsafe import Markup
  4. RECAPTCHA_SCRIPT_DEFAULT = "https://www.google.com/recaptcha/api.js"
  5. RECAPTCHA_DIV_CLASS_DEFAULT = "g-recaptcha"
  6. RECAPTCHA_TEMPLATE = """
  7. <script src='%s' async defer></script>
  8. <div class="%s" %s></div>
  9. """
  10. __all__ = ["RecaptchaWidget"]
  11. class RecaptchaWidget:
  12. def recaptcha_html(self, public_key):
  13. html = current_app.config.get("RECAPTCHA_HTML")
  14. if html:
  15. return Markup(html)
  16. params = current_app.config.get("RECAPTCHA_PARAMETERS")
  17. script = current_app.config.get("RECAPTCHA_SCRIPT")
  18. if not script:
  19. script = RECAPTCHA_SCRIPT_DEFAULT
  20. if params:
  21. script += "?" + urlencode(params)
  22. attrs = current_app.config.get("RECAPTCHA_DATA_ATTRS", {})
  23. attrs["sitekey"] = public_key
  24. snippet = " ".join(f'data-{k}="{attrs[k]}"' for k in attrs) # noqa: B028, B907
  25. div_class = current_app.config.get("RECAPTCHA_DIV_CLASS")
  26. if not div_class:
  27. div_class = RECAPTCHA_DIV_CLASS_DEFAULT
  28. return Markup(RECAPTCHA_TEMPLATE % (script, div_class, snippet))
  29. def __call__(self, field, error=None, **kwargs):
  30. """Returns the recaptcha input HTML."""
  31. try:
  32. public_key = current_app.config["RECAPTCHA_PUBLIC_KEY"]
  33. except KeyError:
  34. raise RuntimeError("RECAPTCHA_PUBLIC_KEY config not set") from None
  35. return self.recaptcha_html(public_key)