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
« 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
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
10__author__ = "Alex Laird"
11__copyright__ = "Copyright 2024, Alex Laird"
12__version__ = "1.0.4"
14logger = logging.getLogger(__name__)
17class AmazonOrders:
18 """
19 Using an authenticated :class:`~amazonorders.session.AmazonSession`, can be used to query Amazon
20 for Order details and history.
21 """
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
30 #: The AmazonSession to use for requests.
31 self.amazon_session: AmazonSession = amazon_session
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
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.
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.")
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
64 for order_tag in response_parsed.find_all("div", {"class": "order-card"}):
65 order = Order(order_tag)
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)
72 orders.append(order)
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")
85 return orders
87 def get_order(self,
88 order_id: str) -> Order:
89 """
90 Get the Amazon order represented by the ID.
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.")
98 self.amazon_session.get("{}/gp/your-account/order-details?orderID={}".format(BASE_URL, order_id))
100 order_details_tag = self.amazon_session.last_response_parsed.find("div", id="orderDetails")
101 order = Order(order_details_tag, full_details=True)
103 return order