def get_presta_data(self, page_num, page_limit): domain = self.shop.domain headers = {"Authorization": self.shop.authheader} sync_type = self.shop.sync_type.lower() result_dict = {} try: # get products initial_index = page_num * page_limit data = get_xml_data("http://%s/api/%s?display=[id,%s,%s,name]&sort=[id_ASC]&limit=%d,%d&price[base_price][use_reduction]=0&price[base_price][use_tax]=0" % (domain, 'products', sync_type, JOINED_ATTRS, initial_index, page_limit), headers) self._get_presta_data(headers, data, result_dict, domain, sync_type, page_limit, page_num) except urllib2.HTTPError as e: error = PrestaError.get_error(PrestaError.DOMAIN, 'Incorrect value', self) if e.code == 500: # This should never happen after we implemented proper pagination message = e.fp.read() send_email.delay('mail/error', {'domain': domain, 'data_list': str(e.message), 'full_data': str(page_num), 'message': str(message)}, "Client Error") error = {PrestaError.DOMAIN: _('You have some problem with API access configuration,<br>' 'try if API works by manually examining url:<br>') + '<a href="http://%s/api/products">http://%s/api/products</a>' % (domain, domain)} elif e.code in (401, 403): # send email about this send_email.delay('mail/error', {'domain': domain, 'data_list': '', 'full_data': '', 'message': ''}, "Incorrect key") error = PrestaError.get_error(PrestaError.KEY, 'Incorrect value', self) if 'attribute_lang' in result_dict: error = PrestaError.get_error(PrestaError.KEY, PrestaError.PROD_COMBINATIONS, self) elif 'product' in result_dict: error = PrestaError.get_error(PrestaError.KEY, PrestaError.PROD_OPTIONS_VALUES, self) elif e.code == 404 or e.code == 503: error = PrestaError.get_error(PrestaError.DOMAIN, PrestaError.NOT_ACTIVATED, self) return result_dict, error except (urllib2.URLError, socket.timeout): # either timeout or dns error error = PrestaError.get_error(PrestaError.DOMAIN, PrestaError.NOT_REACHABLE, self) return result_dict, error except PrestaError, e: # no products found in the shop error = PrestaError.get_error(PrestaError.DOMAIN, e.message, self) return result_dict, error
def module_activate(request): import socket from users.models import Profile from presta.forms import clean_domain from presta.db_logging import log_user_action form = ActivationForm(request.POST) if form.is_valid(): # Check that request goes from the valid domain ip_addr = request.META["REMOTE_ADDR"] domain_name = clean_domain(form.cleaned_data["domain"]).split(":")[0] try: if ip_addr != socket.gethostbyname(domain_name): log_user_action.delay(form.cleaned_data["domain"], "Register IP mismatch", str(ip_addr), "") # return HttpResponseForbidden() except socket.error: log_user_action.delay(form.cleaned_data["domain"], "Socket Error", "Socket error on module activate", "") user, created = Profile.objects.get_or_create(email=form.cleaned_data["email"]) if created: user.set_password(form.cleaned_data["password"]) user.save() shop, created = Shop.objects.get_or_create( domain=form.cleaned_data["domain"], user=user, defaults={"key": form.cleaned_data["key"]} ) # If by some reason shop was already created as temp, make it not temp if not created and shop.temp: shop.temp = False _, error_dict = shop.get_data() if not error_dict: shop.set_ok() elif PrestaError.rewrite_disabled(error_dict): shop.set_alarm(PrestaError.REGEN_HTACCESS) else: shop.set_alarm(error_dict.values()[0]) log_user_action.delay(form.cleaned_data["domain"], "Register Success", "", "") return HttpResponse("ok") raise Http404
def module_activate(request): import socket from users.models import Profile from presta.forms import clean_domain from presta.db_logging import log_user_action form = ActivationForm(request.POST) if form.is_valid(): # Check that request goes from the valid domain ip_addr = request.META['REMOTE_ADDR'] domain_name = clean_domain(form.cleaned_data['domain']).split(':')[0] try: if ip_addr != socket.gethostbyname(domain_name): log_user_action.delay(form.cleaned_data['domain'], "Register IP mismatch", str(ip_addr), "") #return HttpResponseForbidden() except socket.error: log_user_action.delay(form.cleaned_data['domain'], "Socket Error", "Socket error on module activate", "") user, created = Profile.objects.get_or_create(email=form.cleaned_data['email']) if created: user.set_password(form.cleaned_data['password']) user.save() shop, created = Shop.objects.get_or_create(domain=form.cleaned_data['domain'], user=user, defaults={'key': form.cleaned_data['key']}) # If by some reason shop was already created as temp, make it not temp if not created and shop.temp: shop.temp = False _, error_dict = shop.get_data() if not error_dict: shop.set_ok() elif PrestaError.rewrite_disabled(error_dict): shop.set_alarm(PrestaError.REGEN_HTACCESS) else: shop.set_alarm(error_dict.values()[0]) log_user_action.delay(form.cleaned_data['domain'], "Register Success", "", "") return HttpResponse("ok") raise Http404
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