Esempio n. 1
0
class nlbase:
    def __init__(self, pub, priv, shopurl):
        self.pub = pub
        self.priv = priv
        self.url = shopurl

    def connect(self):
        self.wcapi = API(url=self.url,
                         consumer_key=self.pub,
                         consumer_secret=self.priv,
                         wp_api=True,
                         version="wc/v3")
        return [True, {}, None]

    def inputnl(self):
        headers = {
            'Authorization':
            "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE1NTk2NDA0NjgsImV4cCI6MTU1OTY0NDA2OCwicm9sZXMiOlsiUk9MRV9BUEkiXSwidXNlcm5hbWUiOiJhcGkifQ.Zv7v_nDWiHeK-bLHkT3p0GGQ03BaMj5pt-nFWaZZyjkRfQQKjdqNyKXjlZ-GsufPTy9I6LDilP5bGOI_ggKL8AmK5RymEDXp8BAm7Q96mj1fINkj8upu4nx60Zwd3CqCjvZIAC7unV4IsQLA4Q2_Gj2WaFnaeyF8WVxQ91FyAzmOSPD7LmHjUiDkluXNMglukpgYXb0XCOLiEiXLmUZuBqB9s3B4pGeBTFmzHWlXXVvUNIXnJZPua_2LxoeRimPDezTZgyxFn9LMfyjjG__6phgP3xJYAMDkFyf3exovM8D0oj94ZxlRY-zeixcwGf4xVVw69iqTaQtwidE5TS2vc0SYIE1INFn0eNUFk_hLkxYogACFtF3fg3jBqk5j1E7u70L8GQzRuBYpcKnut5nzQTvBDzllp9bKd4L-I0Wu1h9efZWsTz0y6rQITecAEA2nUYAT5UXVkyrWDhrf5E3Yw5uzLMqF-6aEIeDdu4pid4N1yQphjcKCiMqHoGzqldb0wJQUMKbzBszTZ1js7VMFh9HjhYSyifCA3bGzyiy1GKpIRr3gf21UITCH96aZxOVMrSZUGIpWPr9w9dqpSpi69OI-OmlhkYOoVgCSibzh6-Tbq3xz3pQz4TmJMIJTYXh-IuQEjH8r7ZfcYDq3YZ729f9-ZIU1xSLLe8diiyMrQro"
        }
        d = requests.get("http://api2.nleurope.com/api/v1/product",
                         headers=headers).text
        datas = json.loads(d)
        for d in datas:
            try:
                proddata = {
                    "image": str(d[0]["productImage"]),
                    "title": str(d[0]["technicalSheet"]["FR"]["title"]),
                    "flavor": str(d[0]["technicalSheet"]["FR"]["flavor"]),
                    "price": str(d[0]["technicalSheet"]["031"]["pk7ht"]),
                    "prep": str(d[0]["technicalSheet"]["031"]["preparation"]),
                    "ing": str(d[0]["technicalSheet"]["031"]["ingredientList"])
                }
                data = {
                    "name":
                    proddata["title"],
                    "type":
                    "simple",
                    "regular_price":
                    proddata["price"],
                    "description":
                    proddata["flavor"] + proddata["prep"] + proddata["ing"],
                    "short_description":
                    proddata["flavor"],
                    "status":
                    "private",
                    "categories": [],
                    "images": [{
                        "src": proddata["image"]
                    }]
                }
                try:
                    self.wcapi.post("products", data)
                except:
                    return [
                        False, "Wrong Crendential for '" + str(self.url) + "'",
                        401
                    ]
            except:
                print("error")
        return [True, {}, 200]
def main():
    #connecting to your woocommerce REST API
    wcapi = API(
        url="https://your_wordpress_domain.com",
        consumer_key="ck_5e55eb1f8b3po06e47f16bdd733980dc9196a7a6",# your WooCommerce API key this one won't work
        consumer_secret="cs_4aa7999999262fa19224451945ed7f58fa6ac494",# your WooCommerce API secret this one won't work
        wp_api=True,
        query_string_auth=True,
        version="wc/v3"
    )
    # for performance we load all the products in a list
    products  = []
    for x in range(4):
        p = wcapi.get(f"products?per_page=300&offset={300*x}").json()
        products.extend(p)
    # We in each product and use the search engine to find if any updates in the prices
    for x,product in enumerate(products):
        name = product['name']
        price = product['regular_price']
        n_name, n_price, score = get_new_name_and_price(name)
        try:
            score = int(score)
        except:
            score = 0
        if n_name == None or score < 13:
            wcapi.delete(f"products/{product['id']}", params={"force": True}).json()
            print(f'{x} / {score} - Deleted {name} ~ {n_name}')
            if score < 13 and n_name != None: 
                data = {
                    "regular_price": str(n_price),
                    "name": n_name,
                    "status": "publish",
                }
                wcapi.post(f"products", data).json()
                print(f'Created new version of {n_name}')
        else:
            try:
                if float(price) != float(n_price):
                    data = {
                        "regular_price": str(n_price),
                        "name": n_name,
                        "status": "publish",
                    }
                    wcapi.put(f"products/{product['id']}", data).json()
                    print(f'{x} / {score} - Updated {name} ~ {price}')
                    print(f'{x} / {score} - Updated {n_name} ~ {n_price}')
                else:
                    print('Pass')
            except Exception as e:
                print(e)
Esempio n. 3
0
class REQ():
    def __init__(self):

        consumer_admin_key = "ck_7e00fe275804399bba0baf6af01832ac7e1adb5f"
        consumer_admin_secret = "cs_634013c0b6d035d47629da55faf2adf37cde4329"
        self.wcapi = API(url="http://127.0.0.1/akstore",
                         consumer_key=consumer_admin_key,
                         consumer_secret=consumer_admin_secret,
                         version="v3")

    def test_api(self):
        print(self.wcapi.get("").json())

    def post(self, endpoint, data):
        result = self.wcapi.post(endpoint, data)
        rs_code = result.status_code
        rs_body = result.json()
        rs_url = result.url
        return (rs_code, rs_body, rs_url)

    def get(self, endpoint):

        result = self.wcapi.get(endpoint)
        rs_code = result.status_code
        rs_body = result.json()
        rs_url = result.url
        return (rs_code, rs_body, rs_url)

    def wc_cust_delete(self, id):
        result = self.wcapi.delete("customers/" + str(id) + "?force=true")
        return (result).json()

    def wc_product_delete(self, id):
        result = self.wcapi.delete("products/" + str(id) + "?force=true")
        return (result).json()
Esempio n. 4
0
def post_request(path, data):
    settings = get_woocommerce_settings()

    wcapi = API(url=settings['woocommerce_url'],
                consumer_key=settings['api_key'],
                consumer_secret=settings['api_secret'],
                verify_ssl=settings['verify_ssl'],
                wp_api=True,
                version="wc/v3",
                timeout=1000)

    r = wcapi.post(path, data)

    #r.raise_for_status()
    # manually raise for status to get more info from error (message details)
    if r.status_code != requests.codes.ok:
        make_woocommerce_log(title="WooCommerce post error {0}".format(
            r.status_code),
                             status="Error",
                             method="post_request",
                             message="{0}: {1}".format(r.url, r.json()),
                             request_data=data,
                             exception=True)

    return r.json()
    def _call_inventory(self, method, arguments):
        _logger.debug("Start calling Woocommerce api %s", method)
        api = API(url=self.woo.location,
                  consumer_key=self.woo.consumer_key,
                  consumer_secret=self.woo.consumer_secret,
                  version='v2')
        if method == 'product_qty_update':
            if api:
                api_method = 'products/' + str(arguments[0])
                result_dict = {
                    "product": {
                        'stock_quantity': arguments[1]['qty']
                    }
                }

                api.post(api_method, result_dict)
Esempio n. 6
0
class REQ:
    def __init__(self):
        adm_consumer_key = 'ck_f5fcf679cc65d438ba8188e867610e18a6486ee5'
        adm_consumer_secret = 'cs_4c312c0392d86938a4469c432ba15aa78977bb3f'

        self.wcapi = API(url="http://127.0.0.1/ak_store/",
                         consumer_key=adm_consumer_key,
                         consumer_secret=adm_consumer_secret,
                         wp_api=True,
                         version="wc/v2")

    # def test_api(self):
    #     print self.wcapi.get("").json()

    def post(self, endpoint, data):
        result = self.wcapi.post(endpoint, data)

        resp_code = result.status_code
        resp_body = result.json()
        resp_url = result.url

        return [resp_code, resp_body, resp_url]

    def get(self, endpoint):
        result = self.wcapi.get(endpoint)

        resp_code = result.response_code
        resp_body = result.json()
        resp_url = result.url

        return [resp_code, resp_body, resp_url]


# test1 = REQ()
# test1.test_api()
Esempio n. 7
0
class BasicAuth:
    def __init__(self):
        admin_consumer_key = "ck_4c5db02305903c89717481b801f510a50c769cf0"
        admin_consumer_secret = "cs_be0444f22ccc2358bb98193aa39279ce33b78aa8"

        self.wcapi = API(url="http://127.0.0.1/sreenu_store",
                         consumer_key=admin_consumer_key,
                         consumer_secret=admin_consumer_secret,
                         version="v3")

    def test_api(self):
        print(self.wcapi.get("").json())

    def post_method(self, endpoint, data):
        result = self.wcapi.post(endpoint, data)
        rs_response = result.status_code
        rs_body = result.json()
        rs_url = result.url
        return rs_response, rs_body, rs_url

    def get_method(self, endpoint):
        result = self.wcapi.get(endpoint)
        rs_response = result.status_code
        rs_body = result.json()
        rs_url = result.url
        return rs_response, rs_body, rs_url
Esempio n. 8
0
class REQ():
    def __init__(self):
        admin_consumer_key = "ck_82f82456dfe3b95b2b9dc83c56411bb5277807bd"
        admin_consumer_secret = "cs_5af4b6bdfef28ce5337d6a189ef342eb8545079e"

        self.wcapi = API(url="http://127.0.0.1/hbstore/",
                         consumer_key=admin_consumer_key,
                         consumer_secret=admin_consumer_secret,
                         wp_api=True,
                         version="wc/v1")

    def testAPI(self):
        print(self.wcapi.get("").json())

    def post(self, endpoint, data):
        result = self.wcapi.post(endpoint, data)
        res_code = result.status_code
        res_body = result.json()
        res_url = result.url

        return [res_code, res_body, res_url]

    def get(self, endpoint):
        result = self.wcapi.get(endpoint)
        res_code = result.response_code
        res_body = result.json()
        res_url = result.url

        return [res_code, res_body, res_url]


#
# obj = REQ()
# obj.testAPI()
    def _call_order_status(self, method, arguments):
        _logger.debug("Start calling Woocommerce api %s", method)
        api = API(url=self.woo.location,
                  consumer_key=self.woo.consumer_key,
                  consumer_secret=self.woo.consumer_secret,
                  version='v2')
        if method == 'order_status_update':
            if api:
                api_method = 'orders/' + str(arguments[0])
                result_dict = {
                    "order": {
                        'status':
                        arguments[1]['order_history']['id_order_state']
                    }
                }

                api.post(api_method, result_dict)
Esempio n. 10
0
class WooAPIUtility(object):
    def __init__(self):

        wc_creds = CredentialsUtility.get_wc_api_keys()

        self.env = os.environ.get('ENV', 'test')
        self.base_url = WOO_API_HOSTS[self.env]

        self.wcapi = API(url=self.base_url,
                         consumer_key=wc_creds['wc_key'],
                         consumer_secret=wc_creds['wc_secret'],
                         version="wc/v3")

    def assert_status_code(self):
        assert self.status_code == self.expected_status_code, f"Bad Status code." \
          f"Expected {self.expected_status_code}, Actual status code: {self.status_code}," \
          f"URL: {self.endpoint}, Response Json: {self.rs_json}"

    def post(self, wc_endpoint, params=None, expected_status_code=200):

        rs_api = self.wcapi.post(wc_endpoint, data=params)
        self.status_code = rs_api.status_code
        self.expected_status_code = expected_status_code
        self.rs_json = rs_api.json()
        self.endpoint = wc_endpoint
        self.assert_status_code()

        logger.debug(f"POST API response: {self.rs_json}")

        return self.rs_json

    def get(self, wc_endpoint, params=None, expected_status_code=200):

        rs_api = self.wcapi.get(wc_endpoint, params=params)
        self.status_code = rs_api.status_code
        self.expected_status_code = expected_status_code
        self.rs_json = rs_api.json()
        self.endpoint = wc_endpoint
        self.assert_status_code()

        logger.debug(f"GET API response: {self.rs_json}")

        return self.rs_json

    def put(self, wc_endpoint, params=None, expected_status_code=200):

        rs_api = self.wcapi.put(wc_endpoint, data=params)
        self.status_code = rs_api.status_code
        self.expected_status_code = expected_status_code
        self.rs_json = rs_api.json()
        self.endpoint = wc_endpoint
        self.assert_status_code()

        logger.debug(f"PUT API response: {self.rs_json}")

        return self.rs_json
Esempio n. 11
0
def woo_connect(data):
    wcapi = API(url="https://ninjagameden.co.uk",
                consumer_key="",
                consumer_secret="",
                query_string_auth=True)

    new_online_product = wcapi.post("products", data).json()
    print(new_online_product)
    online_id = new_online_product.get('id')
    return online_id
def delete_request(path):
    s = get_request_session()

    wcapi = API(url=settings['woocommerce_url'],
                consumer_key=settings['api_key'],
                consumer_secret=settings['api_secret'],
                verify_ssl=settings['verify_ssl'],
                wp_api=True,
                version="wc/v3",
                timeout=1000)
    r = wcapi.post(path)

    r.raise_for_status()
Esempio n. 13
0
class WooRequestHelper(object):

    def __init__(self):

        creds_helper = CredentialsHelper()
        wc_creds = creds_helper.get_wc_api_keys()

        self.response = None   # if using the pdb debugger the response can be viewed with "pp self.response.json()"
        self.endpoint = None
        self.expected_status_code = None
        self.params = None
        self.wcapi = API(
            url="http://mystore.local",
            consumer_key=wc_creds["wc_key"],
            consumer_secret=wc_creds["wc_secret"],
            version="wc/v3"
        )

    def assert_status_code(self):
        assert self.response.status_code == self.expected_status_code, "Bad Status code. Endpoint: {}, Params: {}. " \
                                                                 "Actual status code: {}, Expected status code: {}," \
                                                                       "Response Body: {}".format(
            self.endpoint, self.params, self.response.status_code, self.expected_status_code, self.response.json())

    def get(self, wc_endpoint, params=None, expected_status_code=200):
        self.response = self.wcapi.get(wc_endpoint, params=params)
        self.endpoint = wc_endpoint
        self.expected_status_code = expected_status_code
        self.params = params
        self.assert_status_code()

        return self.response.json()

    def post(self, wc_endpoint, params=None, expected_status_code=201):
        logger.info("111")
        logger.info(f"Params: {params}")
        logger.info("111")
        self.response = self.wcapi.post(wc_endpoint, data=params)
        self.endpoint = wc_endpoint
        self.expected_status_code = expected_status_code
        self.params = params
        self.assert_status_code()

        return self.response.json()

    def delete(self):
        pass

    def put(self):
        pass
def delete_request(path):
    settings = get_woocommerce_settings()

    wcapi = API(
        url=settings["woocommerce_url"],
        consumer_key=settings["api_key"],
        consumer_secret=settings["api_secret"],
        verify_ssl=settings["verify_ssl"],
        wp_api=True,
        version="wc/v3",
        timeout=1000,
    )
    r = wcapi.post(path)

    r.raise_for_status()
def post_request(path, data):
    settings = get_woocommerce_settings()

    wcapi = API(url=settings['woocommerce_url'],
                consumer_key=settings['api_key'],
                consumer_secret=settings['api_secret'],
                verify_ssl=settings['verify_ssl'],
                wp_api=True,
                version="wc/v3",
                timeout=1000)

    r = wcapi.post(path, data)

    r.raise_for_status()
    return r.json()
Esempio n. 16
0
class WooCommerce(object):
    def __init__(self, url, consumer_key, consumer_secret):
        self.wcapi = API(url=url,
                         consumer_key=consumer_key,
                         consumer_secret=consumer_secret)

    def get_api(self):
        return self.wcapi

    def open_products(self):
        result = self.wcapi.get('products?filter[limit]=1000')
        if result.status_code == 200:
            return result.json()['products']

    def get_products(self, q, limit=1000):
        result = self.wcapi.get(
            'products?filter[q]={q}&filter[limit]={limit}'.format(q=q,
                                                                  limit=1000))
        if result.status_code == 200:
            return result.json()['products']

    def post_product(self, data):
        if len(self.get_products(q=data['product']['title'])) == 0:
            result = self.wcapi.post('products', data=data)
            if result.statu_code == 200:
                return result.json()
        else:
            return "The Products is already exists"

    def get_tags(self):
        result = self.wcapi.get('products/tags')
        if result.status_code == 200:
            return result.json()['product_tags']

    def get_categories(self):
        result = self.wcapi.get('products/categories')
        if result.status_code == 200:
            return result.json()['product_categories']

    def save(self, filename, type='csv'):
        if type == 'csv':
            products = self.get_products()
            keys = products[0].keys()
            with open(filename, 'wb') as output_file:
                dict_writer = csv.DictWriter(output_file, keys)
                dict_writer.writeheader()
                dict_writer.writerows(products)
Esempio n. 17
0
class REQ():
    def __init__(self):
        admin_consumer_key = 'ck_d46283593b62ed3b10e12f646fdc2afccb672575'
        admin_consumer_secret = 'cs_cafbc6686cc0f0a6d1a4a34c2d90ddfda8811822'

        self.wcapi = API(
            url = 'http://127.0.0.1/bkstore',
            consumer_key=admin_consumer_key,
            consumer_secret=admin_consumer_secret,
            version="v3"
        )

    def test_api(self):
        '''

        :return:
        '''
        print self.wcapi.get("").json()
        print self.wcapi.get("").status_code

    def post(self, endpoint, data):
        '''

        :param endpoint:
        :param data:
        :return:
        '''
        result = self.wcapi.post(endpoint, data)
        rs_code = result.status_code
        rs_body = result.json()
        rs_url = result.url

        return [rs_code, rs_body, rs_url]

    def get(self, endpoint):
        '''

        :param endpoint:
        :return:
        '''
        result = self.wcapi.get(endpoint)
        rs_code = result.status_code
        rs_body = result.json()
        rs_url = result.url

        return [rs_code, rs_body, rs_url]
Esempio n. 18
0
class WooRequestsHelper(object):
    def __init__(self):

        creds_helper = CredentialsHelper()
        wc_reds = creds_helper.get_wc_api_keys()

        self.wcapi = API(url="http://mystore.local",
                         consumer_key=wc_reds['wc_key'],
                         consumer_secret=wc_reds['wc_secret'],
                         version="wc/v3")

    def assert_satus_code(self):
        assert self.rs.status_code == self.expected_status_code, "Bad status code. Endpoint: {}, Parmas: {}. " \
        "Actual status code: {}, Expected status code: {}, Response body: {}".format(self.wc_endpoint, self.params, self.rs.status_code,
                                                                  self.expected_status_code, self.rs.json())

    def get(self, wc_endpoint, params=None, expected_status_code=200):
        """

        """
        self.rs = self.wcapi.get(wc_endpoint, params=params)
        self.wc_endpoint = wc_endpoint
        self.expected_status_code = expected_status_code
        self.params = params
        self.assert_satus_code()

        return self.rs.json()

    def post(self, wc_endpoint, params=None, expected_status_code=200):
        """

        """
        self.rs = self.wcapi.post(wc_endpoint, data=params)
        self.wc_endpoint = wc_endpoint
        self.expected_status_code = expected_status_code
        self.params = params
        self.assert_satus_code()

        return self.rs.json()

    def delete(self):
        pass

    def put(self):
        pass
Esempio n. 19
0
class Requests:
    def __init__(self):
        admin_consumer_key = 'ck_e5bf8b09f7dddc049037c01bb6cd540695363b75'
        admin_consumer_secret = 'cs_2543d5b7ed833e6cf83ae4c3e8f2e5f0ccf5538a'

        self.wcapi = API(url="http://127.0.0.1/wp",
                         consumer_key=admin_consumer_key,
                         consumer_secret=admin_consumer_secret,
                         version="wc/v3")

    def test_api(self):
        """

        :return:
        """

        print(self.wcapi.get("").json())

    def post(self, endpoint, data):
        """

        :param endpoint:
        :param data:
        :return:
        """
        result = self.wcapi.post(endpoint, data)
        rs_code = result.status_code
        rs_body = result.json()
        rs_url = result.url

        return [rs_code, rs_body, rs_url]

    def get(self, endpoint):
        """

        :param endpoint:
        :return:
        """
        result = self.wcapi.get(endpoint)
        rs_code = result.status_code
        rs_body = result.json()
        rs_url = result.url

        return [rs_code, rs_body, rs_url]
Esempio n. 20
0
class WooCommerce(object):
	
    def __init__(self, url, consumer_key, consumer_secret):
        self.wcapi = API(url=url, consumer_key=consumer_key, consumer_secret=consumer_secret)

    def get_api(self):
        return self.wcapi

    def open_products(self):
        result = self.wcapi.get('products?filter[limit]=1000')
        if result.status_code == 200:
            return result.json()['products']

    def get_products(self, q, limit=1000):
        result = self.wcapi.get('products?filter[q]={q}&filter[limit]={limit}'.format(q=q, limit=1000))
        if result.status_code == 200:
            return result.json()['products']

    def post_product(self, data):
        if len(self.get_products(q=data['product']['title'])) == 0:
            result = self.wcapi.post('products', data=data)
            if result.statu_code == 200:
                return result.json()
        else:
            return "The Products is already exists"

    def get_tags(self):
        result = self.wcapi.get('products/tags')
        if result.status_code == 200:
            return result.json()['product_tags']

    def get_categories(self):
        result = self.wcapi.get('products/categories')
        if result.status_code == 200:
            return result.json()['product_categories']
        
    def save(self, filename, type='csv'):
        if type == 'csv':
            products = self.get_products()
            keys = products[0].keys()
            with open(filename, 'wb') as output_file:
                dict_writer = csv.DictWriter(output_file, keys)
                dict_writer.writeheader()
                dict_writer.writerows(products)
Esempio n. 21
0
class Request():
    def __init__(self):
        admin_consumer_key = "ck_b8cca2d3ba8e0d7b08c830254b59e1f005df5bd4"
        admin_consumer_secret = "cs_b48bd72801b20cf8df76bee3864d21368f0ef444"

        self.wcapi = API(url="http://127.0.0.1/testapi",
                         consumer_key=admin_consumer_key,
                         consumer_secret=admin_consumer_secret,
                         version="v3")

    def test_api(self):
        """

        :return:
        """
        print self.wcapi.get("").json()

    def post_request(self, endpoint, data):
        """

        :param endpoint:
        :param data:
        :return:
        """
        result = self.wcapi.post(endpoint, data)
        rs_code = result.status_code
        rs_body = result.json()
        rs_url = result.url

        return [rs_code, rs_body, rs_url]

    def get_request(self, endpoint):
        """

        :param endpoint:
        :return:
        """
        result = self.wcapi.get(endpoint)
        rs_code = result.status_code
        rs_body = result.json()
        rs_url = result.url

        return [rs_code, rs_body, rs_url]
Esempio n. 22
0
class Request(object):

    #--------------------------------------------------------------------------------

    def __init__(self):

        self._wcapi = API(
            url=(Conf.API_URL),
            consumer_key=(Conf.API_KEY),
            consumer_secret=(Conf.API_SEC),
            wp_api=(Conf.API_WP),
            version=(Conf.API_VER),
        )

        print("\nAPI Connection Established: {0}\n".format(str(self._wcapi)))

        return None

    #--------------------------------------------------------------------------------

    def test_api_connection(self):
        return self._wcapi.get("").json()

    #--------------------------------------------------------------------------------

    def post(self, end_point, payload):
        result = (self._wcapi.post(end_point, payload))
        response_code = (result.status_code)
        body = (result.json())
        url = (result.url)

        return [response_code, body, url]

    #--------------------------------------------------------------------------------

    def get(self, end_point):
        result = (self._wcapi.get(end_point))
        response_code = (result.status_code)
        body = (result.json())
        url = (result.url)

        return [response_code, body, url]
def post_request(path, data, settings=None):
    if not settings:
        settings = get_woocommerce_settings()
    wcapi = API(url=settings['woocommerce_url'],
                consumer_key=settings['api_key'],
                consumer_secret=settings['password'],
                verify_ssl=True,
                wp_api=True,
                version="wc/v3",
                queryStringAuth=True)
    try:
        r = wcapi.post(path, data)
        r.raise_for_status()
        return r.json()
    except requests.exceptions.HTTPError, e:
        make_woocommerce_log(title=e.message,
                             status="Error",
                             method="post_request",
                             message=r.text,
                             request_data=data,
                             exception=True)
Esempio n. 24
0
chunks_za_update = list(chunks(razlika, 50))

#################################################################################################################
# Postavljanje artikala na Woocommerce                                                                          #
#################################################################################################################

# def postToWc():
#     for artikal in artikli_za_insert:
#         wcapi.post("products", artikal).json()

# postToWc()

#################################################################################################################
# Batch update artikala na Woocommerce                                                                          #
#################################################################################################################
for i in chunks_za_update:
    artikli_za_batch_update = {
        'create': artikli_za_insert,
        'update': i,
        'delete': []
    }

    def BatchPostToWc():
        wcapi.post("products/batch", artikli_za_batch_update).json()

    BatchPostToWc()
    print(wcapi.post("products/batch", artikli_za_batch_update).json())
    print(len(i))

print("--- %s seconds ---" % (time.time() - start_time))
Esempio n. 25
0
wcapi = API(
    url="http://localhost/lab/pythonwoocommerce",
    consumer_key="XX_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    consumer_secret="XX_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    version="wc/v3"
)

data = {
    "name": "Demo Product Name",
    "description": "Demo Product Description",
    "categories": [
        {
            "id": 16
        },
        {
            "id": 17
        }
    ],
    "images": [
        {
            "src": "http://localhost/DemoSite/wp-content/uploads/2020/07/Image-4.jpeg"
        },
        {
            "src": "http://localhost/DemoSite/wp-content/uploads/2018/01/Image-1.jpeg"
        }
    ]
}

print(wcapi.post("products", data).json())
Esempio n. 26
0
    def _call(self, method, endpoint, data=None):
        try:
            api = API(
                url=self.woo.location,
                consumer_key=self.woo.consumer_key,
                consumer_secret=self.woo.consumer_secret,
                version=self.woo.version,
                wp_api=True,
                timeout=None,
            )
            if api:
                if method == 'GET':
                    r = api.get(endpoint)
                elif method == 'POST':
                    r = api.post(endpoint, data)
                elif method == 'PUT':
                    r = api.put(endpoint, data)

                if r.status_code in [200, 201]:
                    res = r.json()
                    _logger.info('%s: %s' % (endpoint, res))
                    return r.json()
                else:
                    code = r.json().get('code')
                    message = r.json().get('message')
                    _logger.info('%s: %s, %s' % (endpoint, code, message))
                    err_res = {'id': None}
                    if 'customers' in endpoint:
                        if code == 'registration-error-email-exists' and method == 'POST':
                            return self._call(method='GET',
                                              endpoint='customers?search=%s' %
                                              data.get('email'))[0]
                        elif code == 'registration-error-invalid-email':
                            return err_res
                        elif code == 'rest_missing_callback_param':
                            return err_res
                        elif code == 'woocommerce_rest_invalid_id':
                            return err_res
                    elif 'products/categories' in endpoint:
                        if code == 'term_exists' and method == 'POST':
                            items = []
                            for item in self._call(
                                    method='GET',
                                    endpoint='products/categories?search=%s' %
                                    data.get('name')):
                                if item.get('name') == data.get(
                                        'name') and data.get(
                                            'parent', 0) == item.get('parent'):
                                    items.append(item)

                            return items[0]
                        elif code == 'woocommerce_rest_term_invalid' and message == 'Resource does not exist.':
                            return err_res
                    elif 'products' in endpoint:
                        if code == 'woocommerce_rest_product_invalid_id':
                            return err_res
                    elif 'orders' in endpoint:
                        if code == 'woocommerce_rest_shop_order_invalid_id':
                            return err_res

        except (socket.gaierror, socket.error, socket.timeout) as err:
            raise NetworkRetryableError(
                'A network error caused the failure of the job: '
                '%s' % err)
        except xmlrpclib.ProtocolError as err:
            if err.errcode in [
                    502,  # Bad gateway
                    503,  # Service unavailable
                    504
            ]:  # Gateway timeout
                raise RetryableJobError(
                    'A protocol error caused the failure of the job:\n'
                    'URL: %s\n'
                    'HTTP/HTTPS headers: %s\n'
                    'Error code: %d\n'
                    'Error message: %s\n' %
                    (err.url, err.headers, err.errcode, err.errmsg))
            else:
                raise
Esempio n. 27
0
from woocommerce import API

wcapi = API(
    url="http://yan-k.safary.xyz/",  # Your store URL
    consumer_key="xxx",  # Your consumer key
    consumer_secret="xxx",  # Your consumer secret
    wp_api=True,  # Enable the WP REST API integration
    version="wc/v3"  # WooCommerce WP REST API version
)

reviews = wcapi.get("products/reviews").json()
products = wcapi.get("products").json()
webhooks = wcapi.get("webhooks").json()

data2 = {
    "name": "Order updated",
    "topic": "ordera.updated",
    "delivery_url": "http://localhost:8000/webhooks/order.updated"
}

data3 = {
    "name": "Review created",
    "topic": "review.created",
    "delivery_url": "http://localhost:8000/webhooks/review.created"
}

data = data3
result3 = wcapi.post("webhooks", data).json()
Esempio n. 28
0
class Request:

    def __init__(self):
        """
        http://woocommerce.github.io/woocommerce-rest-api-docs/
        """
        consumer_key = config['CONNECTION']['consumer_key']
        consumer_secret = config['CONNECTION']['consumer_secret']

        self.wcapi = API(
            url=config['CONNECTION']['url'],
            consumer_key=consumer_key,
            consumer_secret=consumer_secret,
            wp_api=True,
            version="wc/v2"
        )

    def post(self, endpoint, data):
        """
        this method implements POST request to the provided endpoint with provided data in the body.

        :param endpoint: endpoinf for request
        :param data: json body
        :return: lis of elements - response_code, response_body, response_url
        """

        response = self.wcapi.post(endpoint, data)

        response_code = response.status_code
        response_body = response.json()
        response_url = response.url

        return [response_code, response_body, response_url]

    def get(self, endpoint):
        """
        this method implements GET request to the provided endpoint.

        :param endpoint: endpoint for request
        :return: lis of elements - response_code, response_body, response_url
        """

        response = self.wcapi.get(endpoint)

        response_code = response.status_code
        response_body = response.json()
        response_url = response.url

        return [response_code, response_body, response_url]

    def delete(self, endpoint):
        """
        this method implements DELETE request to the provided endpoint

        :param endpoint: endpoint for request
        :return: lis of elements - response_code, response_body, response_url
        """
        response = self.wcapi.delete(endpoint)

        response_code = response.status_code
        response_body = response.json()
        response_url = response.url

        return [response_code, response_body, response_url]

    def put(self, endpoint, data):
        """
        this method implements PUT request to the provided endpoint with provided data
        :param data: json body
        :param endpoint: endpoint for request
        :return: lis of elements - response_code, response_body, response_url
        """
        response = self.wcapi.put(endpoint, data)

        response_code = response.status_code
        response_body = response.json()
        response_url = response.url

        return [response_code, response_body, response_url]
class WooCommerceAPI:
    """ WooCommerce API """
    BASE_URL = "https://catercentral.com.au"

    def __init__(self, username: str, password: str):
        self._username: str = username
        self._password: str = password
        timeout = os.environ.get("API_TIMEOUT") or 600
        self._wcapi = API(url=WooCommerceAPI.BASE_URL,
                          consumer_key=username,
                          consumer_secret=password,
                          version="wc/v3",
                          timeout=timeout)
        self._error_messages = []
        print(f"API timeout set to {timeout}")

    def get_all_products(self, skus: Optional[List] = None):
        """ Get a list of all products """
        success = True
        endpoint = "products"
        params = {"per_page": 100}
        if skus is None:
            response = self._wcapi.get(endpoint=endpoint, params=params)
            return response.json()

        products = []
        while skus:
            skus_in_request = skus[:100]
            skus = skus[100:]
            params["sku"] = ",".join(skus_in_request)
            params["per_page"] = len(skus_in_request)
            response = self._wcapi.get(endpoint=endpoint, params=params)
            if response.ok:
                products += response.json()
            else:
                success = False
        return products, success

    def get_all_products_as_dict(self,
                                 skus: Optional[List] = None
                                 ) -> Tuple[Dict, bool]:
        """ Convert list of products to dict of products with key as SKU """
        products, success = self.get_all_products(skus)
        return {
            product[ApiProductFields.Sku]: product
            for product in products
        }, success

    def update_product(self, product_id: int, data: dict):
        """ Update a product based on id """
        success = False
        endpoint = f"products/{product_id}"
        response = self._wcapi.put(endpoint=endpoint, data=data)
        if response.status_code == 200:
            success = True
        return response.json(), success

    def update_multiple_products(self, data: List[dict]):
        """ Update multiple products in a single API call """
        success = False
        endpoint = f"products/batch"
        data = {"update": data}
        response = self._wcapi.post(endpoint=endpoint, data=data)
        json_response = dict()
        if response.status_code == 200:
            success = True
            json_response = response.json()
            errors = []
            if "update" in json_response:
                errors += [
                    item["error"]["message"]
                    for item in json_response["update"] if "error" in item
                ]
            if errors:
                success = False
                self._error_messages += errors
        return json_response, success

    def create_multiple_products(self, data: List[dict]):
        """ Create multiple products in a single API call """
        success = False
        endpoint = f"products/batch"
        data = {"create": data}
        response = self._wcapi.post(endpoint=endpoint, data=data)
        json_response = dict()
        if response.status_code in (200, 201):
            success = True
            json_response = response.json()
            errors = []
            if "create" in json_response:
                errors += [
                    item["error"]["message"]
                    for item in json_response["create"] if "error" in item
                ]
            if errors:
                success = False
                self._error_messages += errors
        return json_response, success

    def create_or_update_products(self, create_data: List[Dict],
                                  update_data: List[Dict]):
        """ Create or Update products in batch in a single API call """
        # Max of 100 objects can be created or updated
        success = False
        endpoint = f"products/batch"
        data = {"create": create_data, "update": update_data}
        response = self._wcapi.post(endpoint=endpoint, data=data)
        json_response = dict()
        if response.ok:
            success = True
            json_response = response.json()
            errors = []
            if "create" in json_response:
                errors += [
                    item["error"]["message"]
                    for item in json_response["create"] if "error" in item
                ]
            if "update" in json_response:
                errors += [
                    item["error"]["message"]
                    for item in json_response["update"] if "error" in item
                ]
            if errors:
                success = False
                self._error_messages += errors
        return json_response, success

    def get_all_categories(self,
                           search: Optional[str] = None,
                           per_page: Optional[int] = None,
                           parent: Optional[int] = None):
        """ Get list of categories """
        success = False
        endpoint = f"products/categories"
        params = {}
        if search is not None:
            params["search"] = search
        if per_page is not None:
            params["per_page"] = per_page
        if parent is not None:
            params["parent"] = parent
        response = self._wcapi.get(endpoint=endpoint, params=params)
        if response.status_code == 200:
            success = True
        return response.json(), success

    def get_all_attributes(self):
        """ Get a list of product attributes """
        success = False
        endpoint = f"products/attributes"
        response = self._wcapi.get(endpoint=endpoint)
        if response.status_code == 200:
            success = True
        return response.json(), success

    @property
    def errors(self):
        return self._error_messages
Esempio n. 30
0
class WooCommerceShim(Database):
    """
        Contains various methods for interacting with
        the WooCommerce API. These methods will do things
        such as adding new products, and removing sold
        products.
    """
    def __init__(self, *args, **kwargs):
        super(WooCommerceShim, self).__init__(*args, **kwargs)

        # Setup logging
        self.log = logging.getLogger(__name__)
        self.log.setLevel(os.environ.get('log_level', 'INFO'))
        self.log.addHandler(LOG_HANDLER)

        self.api = WCAPI(url=os.environ.get('woo_url', False),
                         consumer_key=os.environ.get('woo_key', False),
                         consumer_secret=os.environ.get('woo_secret', False))

        self.wp_api = WPAPI(url=os.environ.get('woo_url', False),
                            api='wp-json',
                            version='wp/v2',
                            wp_user=os.environ.get('wordpress_user', False),
                            wp_pass=os.environ.get('wordpress_app_password',
                                                   False),
                            basic_auth=True,
                            user_auth=True,
                            consumer_key=False,
                            consumer_secret=False)

        mapping_path = os.environ.get(
            'category_mapping',
            'database/ebay-to-woo-commerce-category-map.json')
        try:
            with open(mapping_path, 'r') as mapping_file:
                self.category_mapping = json.load(mapping_file)
        except IOError:
            self.category_mapping = None

    def __does_image_exist_on_woocommerce(self, slug):
        """
            Searches the Wordpress media library for
            any files that have a URL `slug` that
            matches the one provided

            Returns True if the file exists, and False otherwise

            This method is unreliable! Duplicates are basically guarenteed to happen...
        """

        self.log.info('Checking if a file has a slug matching: %s' % (slug))
        result = self.wp_api.get('/media?slug=%s' % (slug)).json()

        if len(result) == 0:
            return False
        return True

    def __divide_into_chunks(self, iterable, chunk_size=100):
        """
            Used to make bulk requests via the API, which limits
            the amount of products to change at once to 100

            `iterable` is something that can be iterated over, be
            it a list or a range. When a range, you must wrap the
            output of this method in `list()`

            `chunk_size` is optional, and defines how many products
            to change per request. The default of 100 is the maximum
            that the API will allow

            Returns the `iterable` containing as many items as are
            in the `chunk_size`
        """
        for i in range(0, len(iterable), chunk_size):
            yield iterable[i:i + chunk_size]

    def __search_map(self, value, field):
        """
            Uses List Comprehension to search for the `value` in the `field`.

            Normal usage would be similar to `self.__search_map(ebay_category_id, 'ebay_ids')`

            Returns an integer, which is the first matching Woo Commerce ID for
            the selected `value` (in the case that one ebay category is mapped to
            multiple woo commerce categories)

            When a matching category can't be found, this method will call itself
            to search for the "Uncategorized" `value` on the "wc-name" `field`
        """
        try:
            mapped = [
                key for key in self.category_mapping if value in key[field]
            ]
            return int(mapped[0]['wc-id'])
        except IndexError:  # Couldn't find it, return the uncategorized id
            return self.__search_map('Uncategorized', 'wc-name')

    def does_product_exist(self, item_id):
        """
            Determines if the product with the `item_id` has
            already been uploaded to WooCommerce, by checking
            for the truthyness of `post_id`
        """
        data = self.db_get_product_data(item_id)
        if data.get('post_id') is not None:
            return True
        return False

    def get_mapped_category_id(self, ebay_category_id):
        """
            Determines if the user provided a category mapping, and if so
            returns an integer, which is the Woo Commerce category id that
            is mapped to the `ebay_category_id` (or the Uncategorized category
            id if a mapping can not be found)

            In the case that the user has not provided a category mapping,
            this method returns None
        """
        if self.category_mapping is not None:
            return self.__search_map(ebay_category_id, 'ebay_ids')
        return None

    def download_product_images_from_ebay(self, item_id):
        """
            Downloads all of the images for a provided `item_id` and
            returns a dictionary containing the image name, mime type, and
            bytes-like object for the raw images

            The image URLs come from the database table `item_metadata`,
            which is populated when `self.__get_item_metadata()` runs
        """

        count = 0
        return_images = list()

        image_urls = self.db_get_product_image_urls(item_id)
        image_urls_count = len(image_urls)

        if image_urls_count > 0:
            self.log.info("Found %d image URLs for: %s" %
                          (image_urls_count, item_id))

            for image in image_urls:
                url = image.get('value', '')

                if image.get('post_id') is not None:
                    self.log.warning(
                        "We've already uploaded %s, skipping download" % (url))
                    continue

                self.log.info("Downloading %s" % (url))
                req = requests.get(url)

                if req.content:
                    mime_type = req.headers.get('Content-Type', '')
                    slug = '%s-%d' % (item_id, count)
                    extension = mime_type.split('/')[1]
                    filename = '%s.%s' % (slug, extension)

                    if 'image' not in mime_type:
                        msg = "%d didn't get an image somehow. Content type was: %s"
                        self.log.error(msg % (item_id, mime_type))
                        continue

                    return_images.append(
                        Image(slug=slug,
                              ebay_url=url,
                              name=filename,
                              mime_type=mime_type,
                              data=req.content))

                    # self.log.info("Image %s downloaded" % (filename))

                    if count < image_urls_count:
                        self.log.debug(
                            "Waiting a quarter second until next download")
                        time.sleep(0.25)
                else:
                    self.log.error(
                        "No content returned. Is %s reachable in a browser?" %
                        (url))

                count += 1
        else:
            self.log.warning("No Image URLs found for item: %s" % (item_id))

        return return_images

    def upload_image_to_woocommerce(self, image, post_id):
        """
            Uploads the provided `image` to wordpress, and returns the response

            `image` is a dictionary containing the following keys:

            `name` - This is the destination file name, including extension

            `type` - This is the MIMETYPE of the image, usually derived from the extension

            `data` - This is a bytes-like object representing the entire image. We get this
            from dowloading an image directly from Ebay's servers and temporarily storing it
            in memory

            `post_id` is the post in which to attach the image to. This is returned in the
            response from `self.create_product()`

            Returns either a string containing the URL the image can be found at, or False
            if the image fails to be uploaded
        """

        self.log.info("Uploading %s to wordpress" % (image.name))

        endpoint = '/media?post=%d' % (post_id)

        headers = {
            'cache-control': 'no-cache',
            'content-disposition': 'attachment; filename=%s' % (image.name),
            'content-type': '%s' % (image.mime_type)
        }

        # Don't upload a duplicate image if it was uploaded in the past
        if self.__does_image_exist_on_woocommerce(image.slug):
            self.log.warning(
                "Image %s already exists on wordpress. Not uploading again" %
                (image.name))
            return None, None

        # Upload the image
        response = self.wp_api.post(endpoint, image.data, headers=headers)

        try:
            image_id = response.json().get('id')
            url = response.json().get('guid', dict).get('raw')
            self.log.debug("Uploaded %s to %s" % (image.name, url))
            return image_id, url
        except AttributeError:
            self.log.error('Could not upload %s' % image.name)
            return None, None

    def upload_product_images(self, item_id):
        """
            With the provided `item_id`, the database
            is searched for the post id (set during
            `create_product`)

            When the post_id is found, it will be used
            to download the images for that product
            from ebay, and then upload the images
        """
        post_id = self.db_woo_get_post_id(item_id)
        gallery = []

        if post_id is not None:
            for image in self.download_product_images_from_ebay(item_id):
                image_id, url = self.upload_image_to_woocommerce(
                    image, post_id)
                if image_id and url:
                    self.db_metadata_uploaded(image_id, item_id)
                    gallery.append({'id': image_id})

            # Add the images to the gallery
            self.api.put('products/%d' % (post_id), {'images': gallery}).json()
        else:
            self.log.warning('The product %d has not yet been uploaded' %
                             (item_id))

        return self

    def create_product(self, item_id):
        """
            Pulls the product related to the `item_id`
            out of the database and uploads it to WooCommerce

            Returns the result as JSON
        """
        attributes = list()
        attributes_to_upload = list()
        self.log.info('Creating a WooCommerce product from ebay id: %s' %
                      (item_id))

        if self.does_product_exist(item_id):
            self.log.warning(
                'Product with item id %d already exists, skipping' % (item_id))
            return self

        product = self.db_get_product_data(item_id)
        attributes = self.db_get_all_product_metadata(item_id)

        # Strip out any pictures
        attributes = [
            attribute for attribute in attributes
            if attribute['key'] != 'picture_url'
        ]

        # Format the attributes in a way that WooCommerce is expecting
        for index, attribute in enumerate(attributes):
            attributes_to_upload.append({
                'name': attribute['key'],
                'options': [attribute['value']],
                'visible': True,
                'variation': True,
                'position': index,
            })

        upload_data = {
            'name': product['title'],
            'type': 'simple',
            'status': 'publish',
            'short_description': product['condition_description'],
            'description': DEFAULT_DESCRIPTION,
            'sku': product['sku'],
            # 'attributes': attributes_to_upload,
            # 'default_attributes': attributes_to_upload,
        }

        # Add the category id
        category_id = self.get_mapped_category_id(product.get(
            'category_id', 0))
        if category_id is not None:
            upload_data['categories'] = [{'id': category_id}]

        res = self.api.post('products', upload_data).json()

        self.log.debug(res)

        if res.get('id', False):
            self.db_product_uploaded(res['id'], item_id)
        else:
            # Invalid or duplicate sku
            if res.get('code') == 'product_invalid_sku':
                if res.get('data') and res['data'].get('resource_id'):
                    new_post_id = res['data']['resource_id']
                    self.log.warning(
                        'The SKU for %s already exists for %s. Updating.' %
                        (new_post_id, item_id))
                    self.db_product_uploaded(new_post_id, item_id)
            else:
                self.log.error('Unable to retrive product_id')
                self.log.debug(res)
                self.log.debug(upload_data)

        return self

    def delete_product_images(self, item_id):
        """
            With the provided `item_id`, an API request will
            be made to WooCommerce to identify all images
            associted with it. Then, it will delete each of
            those images.
        """

        # This feature has not been implemented.
        # Delete media through wordpress directly

        pass

    def delete_product(self, item_id):
        """
            With the provided `item_id`, an API request will
            be made to WooCommerce to force delete the item

            The `item_id` is supplied by the queue, which gets
            them from `db.db_get_inactive_uploaded_item_ids()`

            When an item is force deleted, it will not appear
            in the "Trash"

            Returns the response as a dictionary or None if
            there is no post id
        """
        post_id = self.db_woo_get_post_id(item_id)
        if post_id is not None:
            self.log.info('Deleting %d from WooCommerce' % (item_id))
            try:
                response = self.api.delete('products/%d' % (post_id),
                                           params={
                                               'force': True
                                           }).json()
            except TypeError:
                self.log.error("Got unexpected response type: %s" %
                               (str(response)))
                return None

            self.delete_product_images(post_id)
            status_code = response.get('data', dict).get('staus', 500)

            if status_code == 404:
                self.log.warning("Product was already deleted")

            elif status_code < 300 and status_code > 199:
                self.log.info('Product deleted')

            else:
                self.log.debug(response)

            return response
        return None

    def delete_all_products_in_range(self, id_range, chunk_size=100):
        """
            With a provided `id_range`, which is expected to be
            a `range` or `list` type, multiple bulk requests
            will be made to the Woo Commerce API to delete
            those items.

            When `id_range` is of type(range), your ending ID needs
            to be the last ID to delete + 1

            Returns None
        """
        self.log.info('Deleting products from %d to %d' %
                      (id_range[0], id_range[-1]))

        # The API says that it supports chunks up to 100 items, but in testing
        # it would always time out, even if it successfully deleted the items
        # with any chunk size greater than or equal to 50
        for chunk in self.__divide_into_chunks(id_range, chunk_size):
            post_ids = list(chunk)
            data = {'delete': post_ids}
            self.api.post('products/batch', data)
            self.log.info('Deleted ids %s' % (post_ids))

            for post_id in post_ids:
                self.delete_product_images(post_id)

    def try_command(self, command, data):
        """
            Wrapper for running methods.

            Verifies that we support the method, raising a NameError if not
            and then runs the method specified in the `command` argument in
            a try, except statement

            `command` is a string that is inside `__available_commands`

            `data` is dependent on the type of command that is being ran.
            In most instances, it is an integer containing the ebay ItemID.

            With the `delete_all_products` command, it is either a range or
            a list containing the post ids for existing products
        """
        __available_commands = [
            'create_product',
            'delete_product',
            'upload_images',
            'delete_all_products',
        ]

        err_msg = "Command %s is unrecognized. Supported commands are: %s" % (
            command, ', '.join(__available_commands))

        if command not in __available_commands:
            self.log.exception(err_msg)
            raise NameError(err_msg)

        try:
            if command == 'create_product':
                return self.create_product(data)

            elif command == 'delete_product':
                return self.delete_product(data)

            elif command == 'upload_images':
                return self.upload_product_images(data)

            elif command == 'delete_all_products':
                return self.delete_all_products_in_range(data)

            else:
                self.log.exception(err_msg)
                raise NameError(err_msg)

        # The several kinds of timeout exceptions that are normally returned by the API
        except (timeout, ReadTimeoutError, requests.exceptions.ConnectTimeout,
                requests.exceptions.ReadTimeout):
            self.log.warning(
                'The Previous request Timed Out. Waiting 5s before retrying')
            time.sleep(5)
            self.try_command(command, data)
Esempio n. 31
0
for idx, record in enumerate(table['records']):
    print("Parsing entry {} of {}".format(idx+1, len(table["records"])))

    #TODO filter by time, don't update everything
    edit_time = record['fields']['Last modified time']
    timestamp = dateutil.parser.parse(edit_time)
    last_update_time = datetime.now()
    
    #if timestamp < last_update_time:

    #delete the old version of the product
    woocommerce_ID = record['fields']['woocommerce_ID']
    wcapi.delete(f"products/{woocommerce_ID}", params={"force": True}).json()

    product = airtable_record_to_json(at, record)
    response = wcapi.post("products", product).json()

    print(product['name'])
    #def update(self, table_name, record_id, data):
    #    if check_string(table_name) and check_string(record_id):
    #        url = posixpath.join(table_name, record_id)
    #        payload = create_payload(data)
    #        return self.__request('PATCH', url,
    #
    # self.headers.update({'Content-type': 'application/json'})
    #    r = requests.request(method,
    #                         posixpath.join(self.base_url, url),
    #                         params=params,
    #                         data=payload,
    #                         headers=self.headers)
    #    if r.status_code == requests.codes.ok:
Esempio n. 32
0
class WooApiHandler:
    def __init__(self):
        self.wcapi = API(
            # WC Office
            url=cred.url,
            consumer_key=cred.consumer_key,
            consumer_secret=cred.consumer_secret,
            version=cred.version,
            timeout=cred.timeout)

        self.products_uploaded = 0
        self.products_updated = 0

        self.PRODUCT_UPLOAD_BATCH_SIZE = 30
        self.PRODUCT_DOWNLOAD_BATCH_SIZE = 100

    def get_sub_categories(self, parent_id):
        """CHANGE WOO PAGE"""

        params = {"per_page": "100", "parent": parent_id}
        get_sub_categories_response = self.wcapi.get("products/categories",
                                                     params=params).json()

        remote_sub_categories = []
        count = 0
        for item in get_sub_categories_response:
            remote_sub_categories.append(self.create_remote_category(item))
            count += 1

        return remote_sub_categories

    def create_remote_category(self, item):
        #print(json.dumps(item, indent=4, sort_keys=True))
        category = Category(html.unescape(item['name']), item['id'])
        category.parent_remote_id = item['parent']
        if item['image']:
            category.image_id = item['image']['id']
        else:
            category.image_id = None
        #category.print_category(1)

        return category

    def get_products(self):
        remote_products = []
        count = 0
        page = 1
        while True:
            params = {
                "per_page": self.PRODUCT_DOWNLOAD_BATCH_SIZE,
                "page": page
            }
            get_products_response = self.wcapi.get("products",
                                                   params=params).json()

            #TEST PRINT
            #print(json.dumps(get_products_response, indent=4, sort_keys=True))

            for woo_product_item in get_products_response:
                remote_products.append(
                    self.create_remote_product(woo_product_item))
                count += 1
            page += 1
            print("DOWLOADED " + str(count) + " PRODUCTS")
            if len(get_products_response) < self.PRODUCT_DOWNLOAD_BATCH_SIZE:
                break

        print(str(count) + " TOTAL PRODUCTS ALREADY ON SITE")
        return remote_products

    def create_remote_product(self, woo_product_item):
        categories = []
        for category in woo_product_item['categories']:
            categories.append(category['id'])
        remote_category_id = categories[0]

        remote_image_ids = []
        for remote_image in woo_product_item['images']:
            remote_image_ids.append(remote_image['id'])

        product_out_price = float(woo_product_item['regular_price'])
        product_out_price = "{0:.2f}".format(product_out_price)

        remoteProduct = RemoteProduct(
            supplier_product_id=woo_product_item['sku'],
            remote_product_id=woo_product_item['id'],
            remote_category_id=remote_category_id,
            product_name=html.unescape(woo_product_item['name']),
            product_description=html.unescape(woo_product_item['description']),
            remote_image_ids=remote_image_ids,
            product_out_price=product_out_price)

        if woo_product_item['sale_price'] != "":
            product_discount_price = float(woo_product_item['sale_price'])
            product_discount_price = "{0:.2f}".format(product_discount_price)
            remoteProduct.product_discount_price = product_discount_price
        else:
            remoteProduct.product_discount_price = "0.0"

        return remoteProduct

    def add_category(self, name, pId):
        data = {"name": name, "display": "default", "parent": pId}
        response = self.wcapi.post("products/categories", data).json()
        # print(json.dumps(response, indent=4, sort_keys=True))

        if "id" in response.keys():
            print("    Uploaded: " + name + " ---> " + str(response['id']))
            return response['id']
        else:
            print("Not Uploaded")
            return ""

    def upload_products(self, products, update):
        """
        When batch upload fails try to upload single products
        Raise batch size to 100
        """

        if update:
            self.print_title("updating products")
        else:
            self.print_title("uploading products")

        uploaded_products = []

        while products:
            product_batch = []
            for i in range(self.PRODUCT_UPLOAD_BATCH_SIZE):
                if products:
                    product_batch.append(products.pop())
                else:
                    break

            data = {}
            create = []
            for product in product_batch:
                if not product.supplier_product_id == "148902":
                    if update:
                        create.append(self.create_woo_update_product(product))
                    else:
                        create.append(self.create_woo_product(product))

            if update:
                data['update'] = create
            else:
                data['create'] = create

            #try:
            batch_upload_response = self.wcapi.post("products/batch",
                                                    data).json()

            if "create" or "update" in batch_upload_response.keys():
                uploaded_products.extend(
                    self.create_remote_products(batch_upload_response))
            else:
                print(
                    json.dumps(batch_upload_response, indent=4,
                               sort_keys=True))
            #except:
            #print("An exception occurred")

        return uploaded_products

    def create_remote_products(self, batch_upload_response):

        #print(json.dumps(batch_upload_response, indent=4, sort_keys=True))
        #print(batch_upload_response['create'])

        uploaded_products = []
        if "create" in batch_upload_response.keys():
            woo_products = batch_upload_response['create']

            for woo_product in woo_products:
                uploaded_products.append(
                    self.create_remote_product(woo_product))
                self.products_uploaded += 1

            #for uploaded_product in uploaded_products:
            #    uploaded_product.print_remote_product()

            print(str(self.products_uploaded) + " TOTAL PRODUCTS UPLOADED")

        if "update" in batch_upload_response.keys():
            woo_products = batch_upload_response['update']

            for woo_product in woo_products:
                uploaded_products.append(
                    self.create_remote_product(woo_product))
                self.products_updated += 1

            # for uploaded_product in uploaded_products:
            #    uploaded_product.print_remote_product()

            print(str(self.products_updated) + " TOTAL PRODUCTS UPDATED")

        return uploaded_products

    def create_woo_update_product(self, product):
        woo_product = {}

        woo_product['id'] = product.remote_product_id

        if product.product_name:
            woo_product['name'] = product.product_name

        if product.product_description:
            woo_product['description'] = product.product_description
            woo_product['short_description'] = product.product_description

        woo_product['regular_price'] = product.product_out_price

        if float(product.product_discount_price) != 0.0:
            woo_product['sale_price'] = product.product_discount_price
        else:
            woo_product['sale_price'] = ""

        return woo_product

    def create_woo_product(self, product):
        woo_product = {}

        cat_id = product.remote_category_id
        # print(catId)

        woo_product['sku'] = product.supplier_product_id
        woo_product['categories'] = [{"id": cat_id}]
        woo_product['name'] = product.product_name
        woo_product['type'] = "simple"
        woo_product['regular_price'] = product.product_out_price
        if float(product.product_discount_price) != 0.0:
            woo_product['sale_price'] = product.product_discount_price
        else:
            woo_product['sale_price'] = ""

        woo_product['description'] = product.product_description
        woo_product['short_description'] = product.product_description
        woo_product['attributes'] = product.product_specification
        woo_product['images'] = product.product_images

        return woo_product

    def update_category_image(self, category, img_ref):
        data = {"image": {"id": img_ref}}

        request = "products/categories/" + str(category.remote_id)
        update_category_image_response = self.wcapi.put(request, data).json()

        #print(json.dumps(update_category_image_response, indent=4, sort_keys=True))

    def update_category_display(self, category, level):
        if level == 1 or level == 2:
            data = {"display": "subcategories"}
            print(category.name + " ---> subcategories")
        else:
            data = {"display": "default"}
            print(category.name + " ---> default")

        request = "products/categories/" + str(category.remote_id)
        update_category_display_response = self.wcapi.put(request, data).json()

    def force_delete_all_products(self):
        params = {"per_page": "100"}
        response_get = self.wcapi.get("products", params=params).json()

        products_to_delete = [d['id'] for d in response_get]
        params = {"force": "True"}

        for p in products_to_delete:
            print(p)
            response_delete = self.wcapi.delete("products/" + str(p),
                                                params=params).json()

    def delete_all_products(self):
        count = 0
        while True:
            params = {"per_page": "100"}
            response_get = self.wcapi.get("products", params=params).json()

            products_to_delete = [d['id'] for d in response_get]
            data = {'delete': products_to_delete}
            response_delete = self.wcapi.post("products/batch", data).json()
            count += len(products_to_delete)
            if len(products_to_delete) < 100:
                break
            else:
                print("Deleted products: " + str(count))

        print("")
        print("Deleted products: " + str(count))

    def delete_all_categories(self):

        count = 0
        while True:
            params = {"per_page": "100"}
            response_get = self.wcapi.get("products/categories",
                                          params=params).json()

            categories_to_delete = [d['id'] for d in response_get]
            data = {'delete': categories_to_delete}
            response_delete = self.wcapi.post("products/categories/batch",
                                              data).json()
            count += len(categories_to_delete)
            if len(categories_to_delete) < 100:
                break
            else:
                print("Deleted categories: " + str(count))

        print("")
        print("Deleted categories: " + str(count))

    def print_title(self, title):
        print("")
        print("----------")
        print("")
        print(title.upper() + ":")
        print("")