Coverage for amazonorders/orders.py: 97.92%

48 statements  

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

1import datetime 

2import logging 

3from typing import List, Optional 

4 

5from amazonorders.conf import DEFAULT_OUTPUT_DIR 

6from amazonorders.entity.order import Order 

7from amazonorders.exception import AmazonOrdersError 

8from amazonorders.session import BASE_URL, AmazonSession 

9 

10__author__ = "Alex Laird" 

11__copyright__ = "Copyright 2024, Alex Laird" 

12__version__ = "1.0.4" 

13 

14logger = logging.getLogger(__name__) 

15 

16 

17class AmazonOrders: 

18 """ 

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

20 for Order details and history. 

21 """ 

22 

23 def __init__(self, 

24 amazon_session: AmazonSession, 

25 debug: bool = False, 

26 output_dir: str = None) -> None: 

27 if not output_dir: 

28 output_dir = DEFAULT_OUTPUT_DIR 

29 

30 #: The AmazonSession to use for requests. 

31 self.amazon_session: AmazonSession = amazon_session 

32 

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

34 self.debug: bool = debug 

35 if self.debug: 

36 logger.setLevel(logging.DEBUG) 

37 #: The directory where any output files will be produced, defaults to ``conf.DEFAULT_OUTPUT_DIR``. 

38 self.output_dir = output_dir 

39 

40 def get_order_history(self, 

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

42 start_index: Optional[int] = None, 

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

44 """ 

45 Get the Amazon order history for the given year. 

46 

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

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

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

50 :return: A list of the requested Orders. 

51 """ 

52 if not self.amazon_session.is_authenticated: 

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

54 

55 orders = [] 

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

57 year, 

58 "&startIndex={}".format( 

59 start_index) if start_index else "") 

60 while next_page: 

61 self.amazon_session.get(next_page) 

62 response_parsed = self.amazon_session.last_response_parsed 

63 

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

65 order = Order(order_tag) 

66 

67 if full_details: 

68 self.amazon_session.get(order.order_details_link) 

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

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

71 

72 orders.append(order) 

73 

74 next_page = None 

75 if start_index is None: 

76 try: 

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

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

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

80 except AttributeError: 

81 logger.debug("No next page") 

82 else: 

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

84 

85 return orders 

86 

87 def get_order(self, 

88 order_id: str) -> Order: 

89 """ 

90 Get the Amazon order represented by the ID. 

91 

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

93 :return: The requested Order. 

94 """ 

95 if not self.amazon_session.is_authenticated: 

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

97 

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

99 

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

101 order = Order(order_details_tag, full_details=True) 

102 

103 return order