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

52 statements  

« prev     ^ index     » next       coverage.py v7.4.0, created at 2024-01-18 21:57 +0000

1import logging 

2from datetime import datetime, date 

3from typing import Optional 

4 

5from bs4 import Tag 

6 

7from amazonorders.entity.parsable import Parsable 

8from amazonorders.entity.seller import Seller 

9from amazonorders.session import BASE_URL 

10 

11__author__ = "Alex Laird" 

12__copyright__ = "Copyright 2024, Alex Laird" 

13__version__ = "1.0.0" 

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_parse(self._parse_title) 

29 #: The Item link. 

30 self.link: str = self.safe_parse(self._parse_link) 

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 

40 def __repr__(self) -> str: 

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

42 

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

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

45 

46 def _parse_title(self) -> str: 

47 tag = self.parsed.find("a") 

48 return tag.text.strip() 

49 

50 def _parse_link(self) -> str: 

51 tag = self.parsed.find("a") 

52 return "{}{}".format(BASE_URL, tag.attrs["href"]) 

53 

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

55 for tag in self.parsed.find_all("div"): 

56 if tag.text.strip().startswith("$"): 

57 return float(tag.text.strip().replace("$", "")) 

58 

59 return None 

60 

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

62 for tag in self.parsed.find_all("div"): 

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

64 return Seller(tag) 

65 

66 return None 

67 

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

69 for tag in self.parsed.find_all("div"): 

70 if "Condition:" in tag.text: 

71 return tag.text.split("Condition:")[1].strip() 

72 

73 return None 

74 

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

76 for tag in self.parsed.find_all("div"): 

77 if "Return" in tag.text: 

78 split_str = "through " 

79 if "closed on " in tag.text: 

80 split_str = "closed on " 

81 clean_str = tag.text.strip() 

82 if split_str in clean_str: 

83 date_str = clean_str.split(split_str)[1] 

84 return datetime.strptime(date_str, "%b %d, %Y").date() 

85 

86 return None