utils.py 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. import hashlib
  2. from typing import TYPE_CHECKING
  3. from .schema import EventMessage
  4. if TYPE_CHECKING:
  5. from apps.issue_events.models import IssueEventType
  6. def default_hash_input(title: str, culprit: str, type: "IssueEventType") -> str:
  7. return title + culprit + str(type)
  8. def generate_hash(
  9. title: str, culprit: str, type: "IssueEventType", extra: list[str] | None = None
  10. ) -> str:
  11. """Generate insecure hash used for grouping issues"""
  12. if extra:
  13. hash_input = "".join(
  14. [
  15. default_hash_input(title, culprit, type)
  16. if part == "{{ default }}"
  17. else (part or "")
  18. for part in extra
  19. ]
  20. )
  21. else:
  22. hash_input = default_hash_input(title, culprit, type)
  23. return hashlib.md5(hash_input.encode()).hexdigest()
  24. def transform_parameterized_message(message: str | EventMessage) -> str:
  25. """
  26. Accept str or Event Message interface
  27. Returns formatted string with interpolation
  28. Both examples would return "Hello there":
  29. {
  30. "message": "Hello %s",
  31. "params": ["there"]
  32. }
  33. {
  34. "message": "Hello {foo}",
  35. "params": {"foo": "there"}
  36. }
  37. """
  38. if isinstance(message, str):
  39. return message
  40. if not message.formatted and message.message:
  41. params = message.params
  42. if isinstance(params, list) and params:
  43. return message.message % tuple(params)
  44. elif isinstance(params, dict):
  45. return message.message.format(**params)
  46. else:
  47. # Params not provided, return message as is
  48. return message.message
  49. return message.formatted
  50. Replacable = str | dict | list
  51. KNOWN_BADS = ["\u0000", "\x00"]
  52. def _clean_string(s: str) -> str:
  53. for char in KNOWN_BADS:
  54. s = s.replace(char, "")
  55. return s
  56. def remove_bad_chars(obj: Replacable) -> Replacable:
  57. """Remove charachers which postgresql cannot store"""
  58. if isinstance(obj, dict):
  59. return {
  60. _clean_string(key): remove_bad_chars(value) for key, value in obj.items()
  61. }
  62. elif isinstance(obj, list):
  63. return [remove_bad_chars(item) for item in obj]
  64. elif isinstance(obj, str):
  65. return _clean_string(obj)
  66. else:
  67. return obj