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

52 statements  

« prev     ^ index     » next       coverage.py v7.4.0, created at 2024-01-16 23:55 +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__ = "0.0.7" 

14 

15logger = logging.getLogger(__name__) 

16 

17 

18class Item(Parsable): 

19 def __init__(self, 

20 parsed: Tag) -> None: 

21 super().__init__(parsed) 

22 

23 self.title: str = self.safe_parse(self._parse_title) 

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

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

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

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

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

29 

30 def __repr__(self) -> str: 

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

32 

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

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

35 

36 def _parse_title(self) -> str: 

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

38 return tag.text.strip() 

39 

40 def _parse_link(self) -> str: 

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

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

43 

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

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

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

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

48 

49 return None 

50 

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

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

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

54 return Seller(tag) 

55 

56 return None 

57 

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

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

60 if "Condition:" in tag.text: 

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

62 

63 return None 

64 

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

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

67 if "Return" in tag.text: 

68 split_str = "through " 

69 if "closed on " in tag.text: 

70 split_str = "closed on " 

71 clean_str = tag.text.strip() 

72 if split_str in clean_str: 

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

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

75 

76 return None