From 3d0f5ddd81cbf5341621b992f07992a56dad947a Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Sun, 27 Nov 2022 14:30:52 -0600 Subject: [PATCH] Sort products when fetching from Woo API default sort is by 'date desc' which is not always determinate also, combine logic for fetching products --- rattail_woocommerce/importing/woocommerce.py | 20 ++----- .../woocommerce/importing/model.py | 25 +++------ rattail_woocommerce/woocommerce/util.py | 53 +++++++++++++++++++ 3 files changed, 63 insertions(+), 35 deletions(-) create mode 100644 rattail_woocommerce/woocommerce/util.py diff --git a/rattail_woocommerce/importing/woocommerce.py b/rattail_woocommerce/importing/woocommerce.py index 81e26bb..5da974f 100644 --- a/rattail_woocommerce/importing/woocommerce.py +++ b/rattail_woocommerce/importing/woocommerce.py @@ -35,6 +35,7 @@ from rattail.core import get_uuid from rattail.util import OrderedDict from rattail.time import localtime, make_utc from rattail_woocommerce import importing as rattail_woocommerce_importing +from rattail_woocommerce.woocommerce.util import get_woocommerce_products class FromWooCommerceToRattail(importing.ToRattailHandler): @@ -68,21 +69,6 @@ class FromWooCommerce(importing.Importer): self.api = WooAPI(**kwargs) - def get_woocommerce_products(self): - products = [] - page = 1 - while True: - block = self.api.get('products', params={'per_page': 100, - 'page': page}) - products.extend(block.json()) - link = block.headers.get('Link') - if link and 'rel="next"' in link: - page += 1 - else: - break - - return products - class ProductImporter(FromWooCommerce, rattail_woocommerce_importing.model.ProductImporter): """ @@ -114,7 +100,7 @@ class ProductImporter(FromWooCommerce, rattail_woocommerce_importing.model.Produ query=query) def get_host_objects(self): - return self.get_woocommerce_products() + return get_woocommerce_products(self.api) def find_rattail_product(self, api_product): product = self.get_product_by_woo_id(api_product['id']) @@ -271,7 +257,7 @@ class WooCacheProductImporter(FromWooCommerce, rattail_woocommerce_importing.mod pass def get_host_objects(self): - return self.get_woocommerce_products() + return get_woocommerce_products(self.api) def normalize_host_object(self, api_product): data = dict(api_product) diff --git a/rattail_woocommerce/woocommerce/importing/model.py b/rattail_woocommerce/woocommerce/importing/model.py index 8628c82..4a8ccb4 100644 --- a/rattail_woocommerce/woocommerce/importing/model.py +++ b/rattail_woocommerce/woocommerce/importing/model.py @@ -2,7 +2,7 @@ ################################################################################ # # Rattail -- Retail Software Framework -# Copyright © 2010-2021 Lance Edgar +# Copyright © 2010-2022 Lance Edgar # # This file is part of Rattail. # @@ -27,6 +27,7 @@ WooCommerce model importers from woocommerce import API as WooAPI from rattail import importing +from rattail_woocommerce.woocommerce.util import get_woocommerce_products class ToWooCommerce(importing.Importer): @@ -114,23 +115,11 @@ class ProductImporter(ToWooCommerce): Fetch existing products from WooCommerce. """ cache = {} - page = 1 - while True: - response = self.api.get('products', params={'per_page': 100, - 'page': page}) - for product in response.json(): - data = self.normalize_local_object(product) - normal = self.normalize_cache_object(product, data) - key = self.get_cache_key(product, normal) - cache[key] = normal - - # TODO: this seems a bit hacky, is there a better way? - link = response.headers.get('Link') - if link and 'rel="next"' in link: - page += 1 - else: - break - + for product in get_woocommerce_products(self.api): + data = self.normalize_local_object(product) + normal = self.normalize_cache_object(product, data) + key = self.get_cache_key(product, normal) + cache[key] = normal return cache def get_single_local_object(self, key): diff --git a/rattail_woocommerce/woocommerce/util.py b/rattail_woocommerce/woocommerce/util.py new file mode 100644 index 0000000..dc5ca04 --- /dev/null +++ b/rattail_woocommerce/woocommerce/util.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8; -*- +################################################################################ +# +# Rattail -- Retail Software Framework +# Copyright © 2010-2022 Lance Edgar +# +# This file is part of Rattail. +# +# Rattail is free software: you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation, either version 3 of the License, or (at your option) any later +# version. +# +# Rattail is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# Rattail. If not, see . +# +################################################################################ +""" +WooCommerce utilities +""" + + +def get_woocommerce_products(api): + """ + Fetch and return all products from Woo API. + """ + products = [] + page = 1 + while True: + + # TODO: 100 seems to be the max allowed per page? + # although docs do not seem to mention a limit.. + # https://woocommerce.github.io/woocommerce-rest-api-docs/?python#list-all-products + response = api.get('products', params={'per_page': 100, + 'page': page, + 'orderby': 'id', + 'order': 'asc'}) + + products.extend(response.json()) + + # TODO: this seems a bit hacky, is there a better way? + link = response.headers.get('Link') + if link and 'rel="next"' in link: + page += 1 + else: + break + + return products