Coverage for apps/ptf/url_utils.py: 27%

41 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2024-06-19 08:36 +0000

1import re 

2from base64 import urlsafe_b64decode 

3from base64 import urlsafe_b64encode 

4from urllib.parse import parse_qs 

5from urllib.parse import urlencode 

6from urllib.parse import urlparse 

7 

8from django.core.exceptions import ValidationError 

9from django.core.validators import URLValidator 

10 

11 

12def validate_url(url: str) -> bool: 

13 """ 

14 Returns whether an absolute URL string is correctly formed. 

15 """ 

16 url_validator = URLValidator(schemes=["http", "https"]) 

17 url_valid = True 

18 

19 try: 

20 url_validator(url) 

21 except ValidationError: 

22 url_valid = False 

23 

24 return url_valid 

25 

26 

27def format_url_with_params(base_url: str, query_params: dict = {}) -> str: 

28 """ 

29 Replace the querystring of the base URL with the given query parameters. 

30 """ 

31 if not query_params: 

32 return base_url 

33 

34 url = urlparse(str(base_url)) 

35 url = url._replace(query=urlencode(query_params, doseq=True)) 

36 return url.geturl() 

37 

38 

39def add_fragment_to_url(base_url: str, fragment: str) -> str: 

40 """Adds a fragment to an URL. Overwrite existing one, if any.""" 

41 url = re.sub(r"#.*$", "", base_url) 

42 return f"{url}#{fragment}" 

43 

44 

45def add_query_parameters_to_url(base_url: str, query_dict: dict[str, list[str]]) -> str: 

46 """ 

47 Add the given query parameters to the given URL. 

48 It keeps the existing query parameters & values. 

49 """ 

50 url = urlparse(str(base_url)) 

51 qs = parse_qs(url.query) 

52 

53 for name, values in query_dict.items(): 

54 if name not in qs: 

55 qs[name] = values 

56 continue 

57 values_to_add = [v for v in values if v not in qs[name]] 

58 if values_to_add: 

59 qs[name] = [*qs[name], *values_to_add] 

60 

61 url = url._replace(query=urlencode(qs, doseq=True)) 

62 return url.geturl() 

63 

64 

65def encode_for_url(string: str) -> str: 

66 """ 

67 Encodes the given string for a safe use in URL. 

68 """ 

69 return urlsafe_b64encode(string.encode()).decode() 

70 

71 

72def decode_from_url(encoded_string: str) -> str: 

73 """ 

74 Decodes the given string previously encoded with `encode_for_url`. 

75 """ 

76 return urlsafe_b64decode(encoded_string).decode()