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
Exemple #2
0
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
Exemple #3
0
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