Coverage for app/venv/lib/python3.14/site-packages/weblate/utils/zammad.py: 31%

41 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-10-07 07:15 +0000

1# Copyright © Michal Čihař <michal@weblate.org> 

2# 

3# SPDX-License-Identifier: GPL-3.0-or-later 

4 

5from __future__ import annotations 

6 

7from typing import TYPE_CHECKING 

8 

9from django.conf import settings 

10from django.core.exceptions import ImproperlyConfigured 

11from requests.exceptions import JSONDecodeError, RequestException 

12 

13from .errors import report_error 

14from .requests import request 

15 

16if TYPE_CHECKING: 16 ↛ 17line 16 didn't jump to line 17 because the condition on line 16 was never true

17 from requests import Response 

18 

19FINGERPRINT = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASw" 

20ERR_UNCONFIGURED = "ZAMMAD_URL is not configured!" 

21ERR_TEMPORARY = "Customer care is currently unavailable." 

22 

23 

24class ZammadError(Exception): 

25 pass 

26 

27 

28def process_zammad_response(response: Response) -> dict: 

29 try: 

30 data = response.json() 

31 except JSONDecodeError as error: 

32 report_error("Zammad JSON response") 

33 raise ZammadError(ERR_TEMPORARY) from error 

34 

35 if "errors" in data: 

36 raise ZammadError(str(data["errors"])) 

37 

38 try: 

39 response.raise_for_status() 

40 except RequestException as error: 

41 report_error("Zammad response status") 

42 raise ZammadError(ERR_TEMPORARY) from error 

43 

44 return data 

45 

46 

47def submit_zammad_ticket( 

48 *, title: str, body: str, name: str, email: str, zammad_url: str | None = None 

49) -> tuple[str, str]: 

50 if zammad_url is None: 

51 zammad_url = settings.ZAMMAD_URL 

52 if not zammad_url: 

53 raise ImproperlyConfigured(ERR_UNCONFIGURED) 

54 

55 config_url = f"{zammad_url}/api/v1/form_config" 

56 

57 response = request( 

58 "POST", config_url, data={"fingerprint": FINGERPRINT, "test": "true"} 

59 ) 

60 data = process_zammad_response(response) 

61 

62 if not data.get("enabled"): 

63 raise ZammadError(ERR_TEMPORARY) 

64 

65 response = request( 

66 "POST", 

67 data["endpoint"], 

68 data={ 

69 "fingerprint": FINGERPRINT, 

70 "test": "true", 

71 "token": data["token"], 

72 "title": title, 

73 "name": name, 

74 "body": body, 

75 "email": email, 

76 }, 

77 timeout=10, 

78 ) 

79 data = process_zammad_response(response) 

80 

81 return ( 

82 f"{zammad_url}/#ticket/zoom/{data['ticket']['id']}", 

83 str(data["ticket"]["number"]), 

84 )