amazon-orders 3.2.6__tar.gz → 3.2.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. {amazon_orders-3.2.6 → amazon_orders-3.2.7}/CHANGELOG.md +7 -1
  2. {amazon_orders-3.2.6/amazon_orders.egg-info → amazon_orders-3.2.7}/PKG-INFO +1 -1
  3. {amazon_orders-3.2.6 → amazon_orders-3.2.7/amazon_orders.egg-info}/PKG-INFO +1 -1
  4. {amazon_orders-3.2.6 → amazon_orders-3.2.7}/amazonorders/__init__.py +1 -1
  5. {amazon_orders-3.2.6 → amazon_orders-3.2.7}/amazonorders/entity/order.py +2 -2
  6. {amazon_orders-3.2.6 → amazon_orders-3.2.7}/amazonorders/orders.py +0 -5
  7. {amazon_orders-3.2.6 → amazon_orders-3.2.7}/amazonorders/selectors.py +5 -5
  8. {amazon_orders-3.2.6 → amazon_orders-3.2.7}/tests/test_cli.py +1 -1
  9. {amazon_orders-3.2.6 → amazon_orders-3.2.7}/tests/test_orders.py +17 -5
  10. {amazon_orders-3.2.6 → amazon_orders-3.2.7}/tests/test_transactions.py +26 -32
  11. {amazon_orders-3.2.6 → amazon_orders-3.2.7}/LICENSE +0 -0
  12. {amazon_orders-3.2.6 → amazon_orders-3.2.7}/MANIFEST.in +0 -0
  13. {amazon_orders-3.2.6 → amazon_orders-3.2.7}/README.md +0 -0
  14. {amazon_orders-3.2.6 → amazon_orders-3.2.7}/amazon_orders.egg-info/SOURCES.txt +0 -0
  15. {amazon_orders-3.2.6 → amazon_orders-3.2.7}/amazon_orders.egg-info/dependency_links.txt +0 -0
  16. {amazon_orders-3.2.6 → amazon_orders-3.2.7}/amazon_orders.egg-info/entry_points.txt +0 -0
  17. {amazon_orders-3.2.6 → amazon_orders-3.2.7}/amazon_orders.egg-info/requires.txt +0 -0
  18. {amazon_orders-3.2.6 → amazon_orders-3.2.7}/amazon_orders.egg-info/top_level.txt +0 -0
  19. {amazon_orders-3.2.6 → amazon_orders-3.2.7}/amazonorders/banner.txt +0 -0
  20. {amazon_orders-3.2.6 → amazon_orders-3.2.7}/amazonorders/cli.py +0 -0
  21. {amazon_orders-3.2.6 → amazon_orders-3.2.7}/amazonorders/conf.py +0 -0
  22. {amazon_orders-3.2.6 → amazon_orders-3.2.7}/amazonorders/constants.py +0 -0
  23. {amazon_orders-3.2.6 → amazon_orders-3.2.7}/amazonorders/entity/__init__.py +0 -0
  24. {amazon_orders-3.2.6 → amazon_orders-3.2.7}/amazonorders/entity/item.py +0 -0
  25. {amazon_orders-3.2.6 → amazon_orders-3.2.7}/amazonorders/entity/parsable.py +0 -0
  26. {amazon_orders-3.2.6 → amazon_orders-3.2.7}/amazonorders/entity/recipient.py +0 -0
  27. {amazon_orders-3.2.6 → amazon_orders-3.2.7}/amazonorders/entity/seller.py +0 -0
  28. {amazon_orders-3.2.6 → amazon_orders-3.2.7}/amazonorders/entity/shipment.py +0 -0
  29. {amazon_orders-3.2.6 → amazon_orders-3.2.7}/amazonorders/entity/transaction.py +0 -0
  30. {amazon_orders-3.2.6 → amazon_orders-3.2.7}/amazonorders/exception.py +0 -0
  31. {amazon_orders-3.2.6 → amazon_orders-3.2.7}/amazonorders/forms.py +0 -0
  32. {amazon_orders-3.2.6 → amazon_orders-3.2.7}/amazonorders/session.py +0 -0
  33. {amazon_orders-3.2.6 → amazon_orders-3.2.7}/amazonorders/transactions.py +0 -0
  34. {amazon_orders-3.2.6 → amazon_orders-3.2.7}/amazonorders/util.py +0 -0
  35. {amazon_orders-3.2.6 → amazon_orders-3.2.7}/pyproject.toml +0 -0
  36. {amazon_orders-3.2.6 → amazon_orders-3.2.7}/setup.cfg +0 -0
  37. {amazon_orders-3.2.6 → amazon_orders-3.2.7}/tests/test_conf.py +0 -0
  38. {amazon_orders-3.2.6 → amazon_orders-3.2.7}/tests/test_session.py +0 -0
  39. {amazon_orders-3.2.6 → amazon_orders-3.2.7}/tests/test_util.py +0 -0
  40. {amazon_orders-3.2.6 → amazon_orders-3.2.7}/tests/testcase.py +0 -0
@@ -4,7 +4,13 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
- ## [Unreleased](https://github.com/alexdlaird/amazon-orders/compare/3.2.6...HEAD)
7
+ ## [Unreleased](https://github.com/alexdlaird/amazon-orders/compare/3.2.7...HEAD)
8
+
9
+ ## [3.2.7](https://github.com/alexdlaird/amazon-orders/compare/3.2.6...3.2.7) - 2025-02-17
10
+
11
+ ### Added
12
+
13
+ - Fixes for parsing Amazon Fresh and Whole Foods Market orders, so they no longer need to be skipped (but their Items and Shipments will still be empty).
8
14
 
9
15
  ## [3.2.6](https://github.com/alexdlaird/amazon-orders/compare/3.2.5...3.2.6) - 2025-02-17
10
16
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: amazon-orders
3
- Version: 3.2.6
3
+ Version: 3.2.7
4
4
  Summary: A CLI and library for interacting with Amazon order history.
5
5
  Maintainer-email: Alex Laird <contact@alexlaird.com>
6
6
  License: MIT License
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: amazon-orders
3
- Version: 3.2.6
3
+ Version: 3.2.7
4
4
  Summary: A CLI and library for interacting with Amazon order history.
5
5
  Maintainer-email: Alex Laird <contact@alexlaird.com>
6
6
  License: MIT License
@@ -1,3 +1,3 @@
1
1
  __copyright__ = "Copyright (c) 2024 Alex Laird"
2
2
  __license__ = "MIT"
3
- __version__ = "3.2.6"
3
+ __version__ = "3.2.7"
@@ -92,7 +92,7 @@ class Order(Parsable):
92
92
  return f"Order #{self.order_number}: {self.items}"
93
93
 
94
94
  def _parse_shipments(self) -> List[Shipment]:
95
- if not self.parsed:
95
+ if not self.parsed or len(util.select(self.parsed, self.config.selectors.ORDER_SKIP_ITEMS)) > 0:
96
96
  return []
97
97
 
98
98
  shipments: List[Shipment] = [self.config.shipment_cls(x, self.config)
@@ -102,7 +102,7 @@ class Order(Parsable):
102
102
  return shipments
103
103
 
104
104
  def _parse_items(self) -> List[Item]:
105
- if not self.parsed:
105
+ if not self.parsed or len(util.select(self.parsed, self.config.selectors.ORDER_SKIP_ITEMS)) > 0:
106
106
  return []
107
107
 
108
108
  items: List[Item] = [self.config.item_cls(x, self.config)
@@ -73,11 +73,6 @@ class AmazonOrders:
73
73
  response_parsed = self.amazon_session.last_response_parsed
74
74
 
75
75
  for order_tag in util.select(response_parsed, self.config.selectors.ORDER_HISTORY_ENTITY_SELECTOR):
76
- # First check if this Order is known to be of a type that we do not currently have a way to support
77
- # parsing, meaning it should be skipped
78
- if util.select(order_tag, self.config.selectors.ORDER_HISTORY_BRAND_SELECTOR):
79
- continue
80
-
81
76
  order: Order = self.config.order_cls(order_tag, self.config)
82
77
 
83
78
  if full_details:
@@ -55,12 +55,12 @@ class Selectors:
55
55
  SHIPMENT_ENTITY_SELECTOR = ["[data-component='orderCard'] [data-component='shipments'] .a-box",
56
56
  "div.shipment",
57
57
  "div.delivery-box"]
58
- # Selectors defined here, if found in an Order, will cause the Order to be skipped, since it means we currently
59
- # do not have a way to support fully parsing its details
60
- ORDER_HISTORY_BRAND_SELECTOR = [
61
- # Amazon Fresh is not supported
58
+ # Selectors defined here mean we don't have a reliable way to parse all details in an Order, so Items and
59
+ # Shipments will be skipped
60
+ ORDER_SKIP_ITEMS = [
61
+ # Identifies an Amazon Fresh order
62
62
  ".brand-info-box .brand-logo img",
63
- # Whole Foods Market is not supported
63
+ # Identifies a Whole Foods Market order
64
64
  "a.yohtmlc-order-details-link[href^='/wholefoodsmarket']"
65
65
  ]
66
66
 
@@ -92,7 +92,7 @@ class TestCli(UnitTestCase):
92
92
  mock_get_today.date.today.return_value = datetime.date(2024, 10, 11)
93
93
  days = 1
94
94
  self.given_login_responses_success()
95
- with open(os.path.join(self.RESOURCES_DIR, "transactions", "get-transactions.html"),
95
+ with open(os.path.join(self.RESOURCES_DIR, "transactions", "get-transactions-snippet.html"),
96
96
  "r", encoding="utf-8") as f:
97
97
  resp = responses.add(
98
98
  responses.GET,
@@ -98,7 +98,7 @@ class TestOrders(UnitTestCase):
98
98
  orders = self.amazon_orders.get_order_history(year=year, start_index=start_index)
99
99
 
100
100
  # THEN
101
- self.assertEqual(9, len(orders))
101
+ self.assertEqual(10, len(orders))
102
102
  self.assertEqual(1, resp1.call_count)
103
103
  self.assertEqual(1, resp2.call_count)
104
104
  order = orders[5]
@@ -139,7 +139,7 @@ class TestOrders(UnitTestCase):
139
139
  self.assertEqual(1, resp3.call_count)
140
140
 
141
141
  @responses.activate
142
- def test_get_order_history_skip_fresh(self):
142
+ def test_get_order_history_fresh(self):
143
143
  # GIVEN
144
144
  self.amazon_session.is_authenticated = True
145
145
  year = 2024
@@ -158,12 +158,18 @@ class TestOrders(UnitTestCase):
158
158
  orders = self.amazon_orders.get_order_history(year=year, start_index=start_index)
159
159
 
160
160
  # THEN
161
- self.assertEqual(9, len(orders))
161
+ self.assertEqual(10, len(orders))
162
162
  self.assertEqual(1, resp1.call_count)
163
163
  self.assertEqual(1, resp2.call_count)
164
+ order = orders[4]
165
+ self.assertEqual("111-2072777-8279433", order.order_number)
166
+ self.assertEqual(80.27, order.grand_total)
167
+ self.assertIsNotNone(order.order_details_link)
168
+ self.assertEqual(date(2025, 1, 3), order.order_placed_date)
169
+ self.assertEqual(0, len(order.items))
164
170
 
165
171
  @responses.activate
166
- def test_get_order_history_skip_wholefoods(self):
172
+ def test_get_order_history_wholefoods(self):
167
173
  # GIVEN
168
174
  self.amazon_session.is_authenticated = True
169
175
  year = 2024
@@ -182,9 +188,15 @@ class TestOrders(UnitTestCase):
182
188
  orders = self.amazon_orders.get_order_history(year=year, start_index=start_index)
183
189
 
184
190
  # THEN
185
- self.assertEqual(9, len(orders))
191
+ self.assertEqual(10, len(orders))
186
192
  self.assertEqual(1, resp1.call_count)
187
193
  self.assertEqual(1, resp2.call_count)
194
+ order = orders[7]
195
+ self.assertEqual("113-6307059-7336242", order.order_number)
196
+ self.assertEqual(62.92, order.grand_total)
197
+ self.assertIsNotNone(order.order_details_link)
198
+ self.assertEqual(date(2024, 12, 12), order.order_placed_date)
199
+ self.assertEqual(0, len(order.items))
188
200
 
189
201
  @responses.activate
190
202
  def test_get_order_history_full_details(self):
@@ -37,11 +37,9 @@ class TestOrders(UnitTestCase):
37
37
  mock_get_today.date.today.return_value = datetime.date(2024, 10, 11)
38
38
  days = 1
39
39
  self.amazon_session.is_authenticated = True
40
- with open(
41
- os.path.join(self.RESOURCES_DIR, "transactions", "get-transactions.html"),
42
- "r",
43
- encoding="utf-8",
44
- ) as f:
40
+ with open(os.path.join(self.RESOURCES_DIR, "transactions", "get-transactions-snippet.html"),
41
+ "r",
42
+ encoding="utf-8") as f:
45
43
  responses.add(
46
44
  responses.GET,
47
45
  f"{self.test_config.constants.TRANSACTION_HISTORY_LANDING_URL}",
@@ -71,11 +69,9 @@ class TestOrders(UnitTestCase):
71
69
  mock_get_today.date.today.return_value = datetime.date(2025, 2, 13)
72
70
  days = 30
73
71
  self.amazon_session.is_authenticated = True
74
- with open(
75
- os.path.join(self.RESOURCES_DIR, "transactions", "transactions-in-progress.html"),
76
- "r",
77
- encoding="utf-8",
78
- ) as f:
72
+ with open(os.path.join(self.RESOURCES_DIR, "transactions", "transactions-in-progress.html"),
73
+ "r",
74
+ encoding="utf-8") as f:
79
75
  responses.add(
80
76
  responses.GET,
81
77
  f"{self.test_config.constants.TRANSACTION_HISTORY_LANDING_URL}",
@@ -109,29 +105,27 @@ class TestOrders(UnitTestCase):
109
105
 
110
106
  def test_parse_transaction_form_tag(self):
111
107
  # GIVEN
112
- with open(
113
- os.path.join(self.RESOURCES_DIR, "transactions", "transaction-form-tag.html"),
114
- "r",
115
- encoding="utf-8",
116
- ) as f:
108
+ with open(os.path.join(self.RESOURCES_DIR, "transactions", "transaction-form-tag.html"),
109
+ "r",
110
+ encoding="utf-8") as f:
117
111
  parsed = BeautifulSoup(f.read(), self.test_config.bs4_parser)
118
112
  form_tag = parsed.select_one("form")
119
113
 
120
- # WHEN
121
- transactions, next_page_url, next_page_data = _parse_transaction_form_tag(
122
- form_tag, self.test_config
123
- )
114
+ # WHEN
115
+ transactions, next_page_url, next_page_data = _parse_transaction_form_tag(
116
+ form_tag, self.test_config
117
+ )
124
118
 
125
- # THEN
126
- self.assertEqual(len(transactions), 2)
127
- self.assertEqual(
128
- next_page_url, "https://www.amazon.com:443/cpe/yourpayments/transactions"
129
- )
130
- self.assertEqual(
131
- next_page_data,
132
- {
133
- "ppw-widgetState": "the-ppw-widgetState",
134
- "ie": "UTF-8",
135
- 'ppw-widgetEvent:DefaultNextPageNavigationEvent:{"nextPageKey":"key"}': "",
136
- },
137
- )
119
+ # THEN
120
+ self.assertEqual(len(transactions), 2)
121
+ self.assertEqual(
122
+ next_page_url, "https://www.amazon.com:443/cpe/yourpayments/transactions"
123
+ )
124
+ self.assertEqual(
125
+ next_page_data,
126
+ {
127
+ "ppw-widgetState": "the-ppw-widgetState",
128
+ "ie": "UTF-8",
129
+ 'ppw-widgetEvent:DefaultNextPageNavigationEvent:{"nextPageKey":"key"}': "",
130
+ },
131
+ )
File without changes
File without changes
File without changes
File without changes