Coverage for amazonorders/orders.py: 97.73%

44 statements  

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

1import datetime 

2import logging 

3from typing import List, Optional 

4 

5from amazonorders.entity.order import Order 

6from amazonorders.exception import AmazonOrdersError 

7from amazonorders.session import BASE_URL, AmazonSession 

8 

9__author__ = "Alex Laird" 

10__copyright__ = "Copyright 2024, Alex Laird" 

11__version__ = "1.0.3" 

12 

13logger = logging.getLogger(__name__) 

14 

15 

16class AmazonOrders: 

17 """ 

18 Using an authenticated :class:`~amazonorders.session.AmazonSession`, can be used to query Amazon 

19 for Order details and history. 

20 """ 

21 

22 def __init__(self, 

23 amazon_session: AmazonSession, 

24 debug: bool = False) -> None: 

25 #: The AmazonSession to use for requests. 

26 self.amazon_session: AmazonSession = amazon_session 

27 

28 #: Set logger ``DEBUG`` and send output to ``stderr``. 

29 self.debug: bool = debug 

30 if self.debug: 

31 logger.setLevel(logging.DEBUG) 

32 

33 def get_order_history(self, 

34 year: int = datetime.date.today().year, 

35 start_index: Optional[int] = None, 

36 full_details: bool = False) -> List[Order]: 

37 """ 

38 Get the Amazon order history for the given year. 

39 

40 :param year: The year for which to get history. 

41 :param start_index: The index to start at within the history. 

42 :param full_details: Will execute an additional request per Order in the retrieved history to fully populate it. 

43 :return: A list of the requested Orders. 

44 """ 

45 if not self.amazon_session.is_authenticated: 

46 raise AmazonOrdersError("Call AmazonSession.login() to authenticate first.") 

47 

48 orders = [] 

49 next_page = "{}/your-orders/orders?timeFilter=year-{}{}".format(BASE_URL, 

50 year, 

51 "&startIndex={}".format( 

52 start_index) if start_index else "") 

53 while next_page: 

54 self.amazon_session.get(next_page) 

55 response_parsed = self.amazon_session.last_response_parsed 

56 

57 for order_tag in response_parsed.find_all("div", {"class": "order-card"}): 

58 order = Order(order_tag) 

59 

60 if full_details: 

61 self.amazon_session.get(order.order_details_link) 

62 order_details_tag = self.amazon_session.last_response_parsed.find("div", id="orderDetails") 

63 order = Order(order_details_tag, full_details=True, clone=order) 

64 

65 orders.append(order) 

66 

67 next_page = None 

68 if start_index is None: 

69 try: 

70 next_page = "{}{}".format(BASE_URL, 

71 response_parsed.find("ul", {"class", "a-pagination"}).find( 

72 "li", {"class": "a-last"}).find("a").attrs["href"]) 

73 except AttributeError: 

74 logger.debug("No next page") 

75 else: 

76 logger.debug("start_index is given, not paging") 

77 

78 return orders 

79 

80 def get_order(self, 

81 order_id: str) -> Order: 

82 """ 

83 Get the Amazon order represented by the ID. 

84 

85 :param order_id: The Amazon Order ID to lookup. 

86 :return: The requested Order. 

87 """ 

88 if not self.amazon_session.is_authenticated: 

89 raise AmazonOrdersError("Call AmazonSession.login() to authenticate first.") 

90 

91 self.amazon_session.get("{}/gp/your-account/order-details?orderID={}".format(BASE_URL, order_id)) 

92 

93 order_details_tag = self.amazon_session.last_response_parsed.find("div", id="orderDetails") 

94 order = Order(order_details_tag, full_details=True) 

95 

96 return order