def _get_presta_data(self, headers, data, result_dict, domain, sync_type, page_limit, page_num): id_lang = self.default_lang presta_version = get_xml_data("http://%s/api/%s?display=[name,value]" % (domain, 'configurations'), headers) presta_db_version = '' sort_attr = '&sort=[id_ASC]' for attr in presta_version.findall('.//configuration'): attr_name = attr.findtext('.//name') if attr_name == 'PS_VERSION_DB': presta_db_version = attr.findtext('.//value') break if presta_db_version == '1.5.5.0': sort_attr = '' # get products initial_index = page_num * page_limit data = get_xml_data("http://%s/api/%s?display=[id,%s,%s,name]%s&limit=%d,%d&price[base_price][use_reduction]=0&price[base_price][use_tax]=0" % (domain, 'products', sync_type, JOINED_ATTRS, sort_attr, initial_index, page_limit), headers) result_dict['product'] = {} result_dict['product_lang'] = {} for elem in data.findall('.//product'): product_id = elem.findtext('.//id') values_dict = {} for attr, formatter in UpdateProductValidator.ATTRS: attr_value = elem.findtext('.//%s' % attr) # TODO: report it if not attr_value: attr_value = '0' values_dict[attr] = formatter(attr_value) result_dict['product'][product_id] = {'sync_type': elem.findtext('.//%s' % sync_type), 'values': values_dict} product_name = elem.findtext(".//language[@id='%s']" % id_lang) if not product_name: try: product_name = elem.findall('.//language')[0].text except KeyError: product_name = _('DUMMY') result_dict['product_lang'][product_id] = product_name # product ids are later used to select combinations product_ids = sorted([int(k) for k in result_dict['product_lang'].keys()]) # if there are no products - ha, didn't expect someone doing this if not product_ids: raise PrestaError(PrestaError.NO_PRODUCTS) max_prod_id = max(product_ids) min_prod_id = min(product_ids) product_ids = str(min_prod_id) + ',' + str(max_prod_id) # Finished is set to True so we can exit the loop if len(result_dict['product_lang'].keys()) < page_limit: self.finished = True else: self.finished = False # get attributes data = get_xml_data("http://%s/api/%s?display=[id,name]" % (domain, 'product_option_values'), headers) result_dict['attribute_lang'] = {} for elem in data.findall('.//product_option_value'): id = elem.findtext('.//id') result_dict['attribute_lang'][id] = elem.findtext(".//language[@id='%s']" % id_lang) if not result_dict['attribute_lang'].get(id): try: result_dict['attribute_lang'][id] = elem.findall('.//language')[0].text except KeyError: result_dict['attribute_lang'][id] = _('DUMMY') # get combinations data = get_xml_data("http://%s/api/%s?display=full&sort=[id_product_ASC]&filter[id_product]=[%s]" % (domain, 'combinations', product_ids), headers) result_dict['product_attribute'] = defaultdict(dict) result_dict['product_attribute_combination'] = {} for elem in data.findall('.//combination'): comb_id = elem.findtext('.//id') prod_id = elem.findtext('.//id_product') # TODO: skip prod_ids that are not present in the 'product' dict # TODO: happens because of prestashop sorting BUG if not prod_id in result_dict['product']: continue values_dict = {} for attr, formatter in UpdateProductValidator.ATTRS: # TODO: hack because we don't have base_price if attr == 'base_price': values_dict[attr] = formatter(elem.findtext('.//%s' % 'price')) else: values_dict[attr] = formatter(elem.findtext('.//%s' % attr)) result_dict['product_attribute'][prod_id][comb_id] =\ {'sync_type': elem.findtext('.//%s' % sync_type), 'values': values_dict} result_dict['product_attribute_combination'][comb_id] = [elem.findtext('.//id') for elem in elem.findall('.//product_option_value')] # get stock_data data = get_xml_data("http://%s/api/%s?display=[id_product,id_product_attribute,quantity]&sort=[id_product_ASC]&filter[id_product]=[%s]" % (domain, 'stock_availables', product_ids), headers) for elem in data.findall('.//stock_available'): prod_id = elem.findtext('.//id_product') comb_id = elem.findtext('.//id_product_attribute') quantity = elem.findtext('.//quantity') # TODO: log? # sometimes prod_id is empty - this is weird but we need to handle it if prod_id: # TODO: check why prod_id does not exist, may be convert to dict from defaultdict if comb_id != '0' and prod_id in result_dict['product_attribute']: # Weird situation again we should check whether comb_id present, # sometimes it's not. TODO: log? try: result_dict['product_attribute'][prod_id][comb_id]['values']['quantity'] = quantity except KeyError: pass else: # TODO: skip prod_ids that are not present in the 'product' dict # TODO: happens because of sorting bug if prod_id in result_dict['product']: result_dict['product'][prod_id]['values']['quantity'] = quantity # change values format back: products = [] for prod_id, values in result_dict['product'].iteritems(): products.append((prod_id, values['sync_type'], values['values'])) result_dict['product'] = products product_attributes = defaultdict(list) for prod_id, values in result_dict['product_attribute'].iteritems(): for comb_id, values in values.items(): product_attributes[prod_id].append((comb_id, values['sync_type'], values['values'])) products.append((prod_id, values['sync_type'], values['values'])) result_dict['product_attribute'] = product_attributes