Coverage for app / helpers / validators.py: 77%

22 statements  

« prev     ^ index     » next       coverage.py v7.12.0, created at 2025-12-06 04:49 +0000

1""" 

2Validators 

3""" 

4import re 

5 

6import requests 

7from wtforms.validators import URL, ValidationError 

8 

9 

10# pylint: disable=too-few-public-methods 

11class ValidImageUrl(URL): 

12 """ 

13 Validator to ensure a given URL points to a valid image resource. 

14 

15 This class extends the functionality of a URL validator to include additional 

16 checks to verify that the URL points to an actual image resource. It performs 

17 an HTTP HEAD request to determine if the resource exists and validates 

18 that the content type is an image format. 

19 

20 :ivar message: Custom error message to be displayed when validation fails. 

21 :type message: str 

22 """ 

23 def __init__(self, message=None): 

24 super().__init__(require_tld=True, allow_ip=True, message=message) 

25 

26 def __call__(self, form, field): 

27 super().__call__(form, field) 

28 try: 

29 response = requests.head(field.data, allow_redirects=True, timeout=5) 

30 content_type = response.headers.get('Content-Type', '') 

31 if response.status_code != 200 or not content_type.startswith('image/'): 31 ↛ 32line 31 didn't jump to line 32 because the condition on line 31 was never true

32 raise ValidationError(f"{self.message}: {field.data} " + 

33 f"status code: {response.status_code} " + 

34 f"content type: {content_type}") 

35 except requests.RequestException as e: 

36 raise ValidationError(f"{self.message}: {field.data}") from e 

37 

38 

39class ValidAmazonLink(URL): 

40 """ 

41 WTForms validator that checks if a URL is a valid Amazon book product page. 

42 Extends the built-in URL validator. 

43 """ 

44 # Regex for Amazon book product URLs 

45 amazon_book_pattern = re.compile( 

46 r'^https?://(www\.)?amazon\.' 

47 r'(com|co\.uk|ca|de|fr|es|it|nl|se|pl|in|com\.br|com\.mx|com\.au|co\.jp|cn|sg|ae|sa|tr)' 

48 r'/(?:[^/]+/)?(?:dp|gp/product)/([A-Z0-9]{10})(?:/[^/])*/?[^?]*(?:|\?[^?]*)$', 

49 re.IGNORECASE 

50 ) 

51 

52 def __call__(self, form, field): 

53 # First, run the base URL validator 

54 super().__call__(form, field) 

55 url = field.data 

56 

57 # Now, check for the Amazon book product URL pattern 

58 if not self.amazon_book_pattern.match(url): 58 ↛ 59line 58 didn't jump to line 59 because the condition on line 58 was never true

59 raise ValidationError( 

60 f"URL {url} must be a valid Amazon book product page " + 

61 "(e.g., https://www.amazon.com/dp/XXXXXXXXXX)" 

62 )