Coverage for amazonorders/entity/item.py: 100.00%

56 statements  

« prev     ^ index     » next       coverage.py v7.4.1, created at 2024-01-29 14:37 +0000

1import logging 

2from datetime import datetime, date 

3from typing import Optional 

4 

5from bs4 import Tag 

6 

7from amazonorders import constants 

8from amazonorders.entity.parsable import Parsable 

9from amazonorders.entity.seller import Seller 

10 

11__author__ = "Alex Laird" 

12__copyright__ = "Copyright 2024, Alex Laird" 

13__version__ = "1.0.7" 

14 

15logger = logging.getLogger(__name__) 

16 

17 

18class Item(Parsable): 

19 """ 

20 An Item in an Amazon `~amazonorders.entity.order.Order`. 

21 """ 

22 

23 def __init__(self, 

24 parsed: Tag) -> None: 

25 super().__init__(parsed) 

26 

27 #: The Item title. 

28 self.title: str = self.safe_simple_parse(selector=constants.FIELD_ITEM_TITLE_SELECTOR, required=True) 

29 #: The Item link. 

30 self.link: str = self.safe_simple_parse(selector=constants.FIELD_ITEM_LINK_SELECTOR, link=True, required=True) 

31 #: The Item price. 

32 self.price: Optional[float] = self.safe_parse(self._parse_price) 

33 #: The Item Seller. 

34 self.seller: Optional[Seller] = self.safe_parse(self._parse_seller) 

35 #: The Item condition. 

36 self.condition: Optional[str] = self.safe_parse(self._parse_condition) 

37 #: The Item return eligible date. 

38 self.return_eligible_date: Optional[date] = self.safe_parse(self._parse_return_eligible_date) 

39 #: The Item image URL. 

40 self.image_link: Optional[str] = self.safe_simple_parse(selector=constants.FIELD_ITEM_IMG_LINK_SELECTOR, 

41 link=True) 

42 #: The Item quantity. 

43 self.quantity: Optional[int] = self.safe_simple_parse(selector=constants.FIELD_ITEM_QUANTITY_SELECTOR, 

44 return_type=int) 

45 

46 def __repr__(self) -> str: 

47 return "<Item: \"{}\">".format(self.title) 

48 

49 def __str__(self) -> str: # pragma: no cover 

50 return "Item: {}".format(self.title) 

51 

52 def __lt__(self, other): 

53 return self.title < other.title 

54 

55 def _parse_price(self) -> Optional[float]: 

56 value = None 

57 

58 for tag in self.parsed.select(constants.FIELD_ITEM_TAG_ITERATOR_SELECTOR): 

59 price = tag.text.strip() 

60 if price.startswith("$"): 

61 value = float(price.replace("$", "")) 

62 

63 return value 

64 

65 def _parse_seller(self) -> Optional[Seller]: 

66 value = None 

67 

68 for tag in self.parsed.select(constants.FIELD_ITEM_TAG_ITERATOR_SELECTOR): 

69 if "Sold by:" in tag.text: 

70 value = Seller(tag) 

71 

72 return value 

73 

74 def _parse_condition(self) -> Optional[str]: 

75 value = None 

76 

77 for tag in self.parsed.select(constants.FIELD_ITEM_TAG_ITERATOR_SELECTOR): 

78 split_str = "Condition:" 

79 if split_str in tag.text: 

80 value = tag.text.split(split_str)[1].strip() 

81 

82 return value 

83 

84 def _parse_return_eligible_date(self) -> Optional[date]: 

85 value = None 

86 

87 for tag in self.parsed.select(constants.FIELD_ITEM_TAG_ITERATOR_SELECTOR): 

88 if "Return" in tag.text: 

89 tag_str = tag.text.strip() 

90 split_str = "through " 

91 if "closed on " in tag.text: 

92 split_str = "closed on " 

93 if split_str in tag_str: 

94 date_str = tag_str.split(split_str)[1] 

95 value = datetime.strptime(date_str, "%b %d, %Y").date() 

96 

97 return value