Coverage for amazonorders/orders.py: 96.30%

54 statements  

« prev     ^ index     » next       coverage.py v7.4.1, created at 2024-02-07 21:56 +0000

1import datetime 

2import logging 

3from typing import List, Optional 

4 

5from amazonorders import constants 

6from amazonorders.conf import DEFAULT_OUTPUT_DIR 

7from amazonorders.entity.order import Order 

8from amazonorders.exception import AmazonOrdersError 

9from amazonorders.session import AmazonSession 

10 

11__author__ = "Alex Laird" 

12__copyright__ = "Copyright 2024, Alex Laird" 

13__version__ = "1.0.7" 

14 

15logger = logging.getLogger(__name__) 

16 

17 

18class AmazonOrders: 

19 """ 

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

21 for Order details and history. 

22 """ 

23 

24 def __init__(self, 

25 amazon_session: AmazonSession, 

26 debug: bool = False, 

27 output_dir: str = None) -> None: 

28 if not output_dir: 

29 output_dir = DEFAULT_OUTPUT_DIR 

30 

31 #: The AmazonSession to use for requests. 

32 self.amazon_session: AmazonSession = amazon_session 

33 

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

35 self.debug: bool = debug 

36 if self.debug: 

37 logger.setLevel(logging.DEBUG) 

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

39 self.output_dir = output_dir 

40 

41 def get_order_history(self, 

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

43 start_index: Optional[int] = None, 

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

45 """ 

46 Get the Amazon order history for the given year. 

47 

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

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

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

51 :return: A list of the requested Orders. 

52 """ 

53 if not self.amazon_session.is_authenticated: 

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

55 

56 self.amazon_session.get(constants.ORDER_HISTORY_LANDING_URL) 

57 if not self.amazon_session.last_response_parsed.select_one("select[name='timeFilter']"): 

58 constants.HISTORY_FILTER_QUERY_PARAM = "orderFilter" 

59 

60 orders = [] 

61 next_page = "{}?{}=year-{}{}".format(constants.ORDER_HISTORY_URL, 

62 constants.HISTORY_FILTER_QUERY_PARAM, 

63 year, 

64 "&startIndex={}".format(start_index) if start_index else "") 

65 while next_page: 

66 self.amazon_session.get(next_page) 

67 response_parsed = self.amazon_session.last_response_parsed 

68 

69 for order_tag in response_parsed.select(constants.ORDER_HISTORY_ENTITY_SELECTOR): 

70 order = Order(order_tag) 

71 

72 if full_details: 

73 self.amazon_session.get(order.order_details_link) 

74 order_details_tag = self.amazon_session.last_response_parsed.select_one( 

75 constants.ORDER_DETAILS_ENTITY_SELECTOR) 

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

77 

78 orders.append(order) 

79 

80 next_page = None 

81 if start_index is None: 

82 next_page_tag = response_parsed.select_one(constants.NEXT_PAGE_LINK_SELECTOR) 

83 if next_page_tag: 

84 next_page = next_page_tag["href"] 

85 if not next_page.startswith("http"): 

86 next_page = "{}{}".format(constants.BASE_URL, next_page) 

87 else: 

88 logger.debug("No next page") 

89 else: 

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

91 

92 return orders 

93 

94 def get_order(self, 

95 order_id: str) -> Order: 

96 """ 

97 Get the Amazon order represented by the ID. 

98 

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

100 :return: The requested Order. 

101 """ 

102 if not self.amazon_session.is_authenticated: 

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

104 

105 self.amazon_session.get("{}?orderID={}".format(constants.ORDER_DETAILS_URL, order_id)) 

106 

107 order_details_tag = self.amazon_session.last_response_parsed.select_one(constants.ORDER_DETAILS_ENTITY_SELECTOR) 

108 order = Order(order_details_tag, full_details=True) 

109 

110 return order