예제 #1
0
print(prestashop.get(''))
print(prestashop.head(''))
print(prestashop.get('addresses', 1))
print(prestashop.get('products', 1))

address_data = prestashop.get('addresses', 1)
address_data['address']['firstname'] = 'Robert'
prestashop.edit('addresses', address_data)

address_data = prestashop.get('addresses', options={'schema': 'blank'})
address_data['address'].update({'address1': '1 Infinite Loop',
                                'address2': '',
                                'alias': 'manufacturer',
                                'city': 'Cupertino',
                                'company': '',
                                'deleted': '0',
                                'dni': '',
                                'firstname': 'STEVE',
                                'id_country': '21',
                                'id_customer': '',
                                'id_manufacturer': '1',
                                'id_state': '5',
                                'id_supplier': '',
                                'lastname': 'JOBY',
                                'other': '',
                                'phone': '(800) 275-2273',
                                'phone_mobile': '',
                                'postcode': '95014',
                                'vat_number': ''})
prestashop.add('addresses', address_data)
            'state': 1,
            'show_price': 1,
            'low_stock_alert': 0,
        }
    }
    if p['slug']:
        slug = p['slug'][:32]
    else:
        slug = slugify(p['name'])
    blank_product['product'].update({'reference': slug})

    if p['regular_price']:
        blank_product['product'].update({'price': float(p['regular_price'])})

    pprint(blank_product)
    result = prestashop.add('products', blank_product)
    new_product_id = result['prestashop']['product']['id']

    seller_product = {
        'kbsellerproduct': {
            "id_seller": seller_id,
            "id_product": new_product_id,
            "id_shop": id_shop,
            "approved": 1,
            "deleted": 0,
        }
    }
    result = prestashop.add('kbsellerproducts', seller_product)
    if url_img:
        print('Downloading image', url_img)
        path = urllib.parse.urlparse(url_img).path
예제 #3
0
class PrestaAdder:
    
    def __init__(self):
        self.prestashop = PrestaShopWebServiceDict('http://www.casalinisport.com/api', 'QAOHGC3FFW9SCOC9MBUVDWNCHB759IYW')  # messages will be as dict
        self.categories={}
        self.manufacturers={}
        self.catschema=self.prestashop.get('categories', options={'schema': 'blank'})
        self.prodschema=self.prestashop.get('products', options={'schema': 'blank'})
        self.manuschema=self.prestashop.get('manufacturers', options={'schema': 'blank'})
        self.skipcats={}
        #self.fetch_categories()
        #self.fetch_manufacturers()
        self.pp = pprint.PrettyPrinter(indent=4)
        self.fproderr = open('proderr','w')
        self.fcaterr = open('caterr','w')

        print "PrestaAdder is ACTIVE, schemas loaded"


    def close_errfiles(self):
        self.fproderr.close()
        self.fcaterr.close()


    #prendo tutte le categorie presenti sul server di destinazione
    def fetch_categories(self):
        cats=self.prestashop.get('categories?display=[name,id]')
        for c in cats['categories']['category']:
            self.categories[c['name']['language']['value']]=c['id']
       

    #prendo tutte le categorie presenti sul server di destinazione
    def fetch_manufacturers(self):
        manu=self.prestashop.get('manufacturers?display=[name,id]')
        for m in manu['manufacturers']['manufacturer']:
            self.manufacturers[m['name']]=m['id']
        
    def safeescape(self,s):
        s=s.replace('"',' pollici')
        s=s.replace('/',' ')
        s=s.replace('   ',' ')
        return s

    #inserisce le categorie se no esistono e ritorna l'id della categoria inserita (l'ultima sottocategoria)
    def add_categorytree(self,cats):
        #inserisco le categorie se non ci sono
        wholestring=""
        fathercat=35 #home
        for c in cats:
            wholestring=wholestring+'_'+c
            #print wholestring
            if not wholestring in self.categories:
                catego=self.catschema['category']
                catego['id_parent']='{0}'.format(fathercat)
                catego['active']='1'
                c=self.safeescape(c)
                c=c.replace('.','')
                catego['name']['language']['value']=c
                catego['link_rewrite']['language']['value']=c.replace(' ','-')
                #catego['description']['language']['value']=c
                #catego['description']['language']['value']="mah un abella nuova categoria"
                self.catschema['category']=catego
                #print self.catschema
                
                try:
                    r=self.prestashop.add('categories',self.catschema)
                except:
                    print "***Error while adding category {0}".format(c)
                    self.fcaterr.write("***Error while adding category {0}\n".format(c))
                    return None
                
                self.categories[wholestring]=r['prestashop']['category']['id']

            fathercat=self.categories[wholestring] #sara padre del prossimo

        return fathercat


#inserisce e ritrna manufacturer
    def add_manufacturer(self,name):
        if not name:
            return None
        if not name in self.manufacturers:
            m=self.manuschema['manufacturer']
            m['name']=name
            m['active']='1'
            #m['link_rewrite']=name.replace(' ','-')
            try:
                r=self.prestashop.add('manufacturers',self.manuschema)
            except:
                print "***Error while adding manufacturer {0}".format(name)
                return None
            self.manufacturers[name]=r['prestashop']['manufacturer']['id']
        
        return self.manufacturers[name]




    def reset_prodschema(self):
        p=self.prodschema['product']
        p['wholesale_price']=None
        p['price']=None
        p['name']['language']['value']=None


#carica immagine prodotto
    def add_prod_img(self,prodid,imgurl,idx):
        f = open('tmp','wb')
        f.write(requests.get(imgurl).content)
        f.close()
        fd        = io.open("tmp", "rb")
        content   = fd.read()
        fd.close()

        #self.prestashop.add('images/products/{0}'.format(prodid), files=[('image',  content)])
        files = {'image': ('image-{0}.png'.format(idx), open('tmp', 'rb'))}
        try:
            r=requests.post('http://www.casalinisport.com/api/images/products/{0}'.format(prodid),files=files, auth=HTTPBasicAuth('QAOHGC3FFW9SCOC9MBUVDWNCHB759IYW', ''))
        except:
            print "ERROROROROROROOR adding image {0}".format(r.status_code)
            print r.text
            self.fproderr.write('***Error adding product image for product {0}'.format(prodid))
            return
        if r.status_code==200 or r.status_code==201:
            print "image added"
        else:
            print "ERROROROROROROOR adding image {0}".format(r.status_code)
            print r.text
            self.fproderr.write('***Error adding product image for product {0}'.format(prodid))

#aggiunge un prodotto
    def add_product(self,prod):
        
        self.reset_prodschema()
        catid=self.add_categorytree(prod['categories'])
        manuid=self.add_manufacturer(prod['manufacturer'])
        
        if not catid or not manuid:
            print "***Error adding product related"# {0}".format(prod['name'])
            self.fproderr.write("***Error adding product related {0}".format(prod['url']))
            return False

        prod['name']=self.safeescape(prod['name'])
        #prod['desc']=self.safeescape(prod['desc'])
        #prod['short_desc']=self.safeescape(prod['short_desc'])
        
        p=self.prodschema['product']
        try:
            p['price']='{0}'.format(prod['prices'][0])
            if len(prod['prices'])>1:
                #p['wholesale_price']='{0}'.format(prod['prices'][1])
                p['price']='{0}'.format(prod['prices'][1])
        except:
            self.fproderr.write('**ERROR no price for this product\n')
            print '**ERROR no price for this product'
            p['price']='1'
        spl=prod['url'].split('/')
        spl=spl[len(spl)-1]
        spl=spl[:spl.find('.')]
        p['link_rewrite']['language']['value']=spl
        p['name']['language']['value']=prod['name']
        p['id_category_default']=catid
        p['associations']['categories']['category']['id']=catid
        if manuid:
            p['id_manufacturer']=manuid
        p['description']['language']['value']=prod['desc']
        p['description_short']['language']['value']=prod['short_desc']
        p['active']='0'
        #p['available_for_order']='1'
        p['show_price']='1'
        p['wholesale_price']=''
        n=len(prod['code'])
        if n>31:
            n=31
        p['reference']=prod['code'][:n]
        #self.pp.pprint(self.prodschema)
        try:
            r=self.prestashop.add("products",self.prodschema)
        except:
            print '**Error adding product {0}\n'.format(prod['url'])
            #self.pp.pprint(self.prodschema)
            self.fproderr.write('**Error adding product {0}\n'.format(prod['url']))
            return False
        
        print "prod added id "+r['prestashop']['product']['id']
        
        i=0
        for img in prod['imgurls']:
            self.add_prod_img(r['prestashop']['product']['id'],img,i)
            i+=1
예제 #4
0
class Api(Core):
    def __init__(self, frame, log_interface, dsn, ip, key, debug=DebugApi()):
        """
        NB : The application is trying to connect at the instantiation of the object
        If you want to connect manually, use the connect() method
        :type frame: Tk
        :type log_interface: Log
        :type dsn: str
        :type ip: str
        :type key: str
        """
        super().__init__(frame, log_interface)
        # UI parameters
        self.dsn = dsn
        self.ip = ip
        self.key = key
        # DB
        self.gdr_db = DatabaseODBC()
        # Api
        self.api = None
        # Connect
        # self.i_log.draw_logs = False
        self.connect()
        # self.i_log.draw_logs = True
        # Debug
        self.debug = debug

    def connect(self):
        """
        Connects to the API and the GDR DB
        """
        # GDR connection
        self.i_log.add("Connexion à la BDD GDR")
        if self.gdr_db.connect(self.dsn):
            self.i_log.add("Connexion réussie")
        else:
            self.i_log.add("Connexion échouée")
        # Api connection
        self.i_log.add("Connexion à l'API")
        self.api = PrestaShopWebServiceDict(self.ip, self.key)
        try:
            self.api.get('')
            self.i_log.add("Connexion réussie")
        # PrestaShopAuthentificationError inherits of PrestaShopWebServiceError
        except PrestaShopAuthenticationError as PSAuthErr:
            self.i_log.add(f"Authentification échouée : {PSAuthErr}")
        except PrestaShopWebServiceError as PSWebServiceErr:
            self.i_log.add(f"Connexion échouée : {PSWebServiceErr}")

    def add_id(self, id_product, title, cat_name):
        gdr_cur = self.gdr_db.DB.cursor()
        # Photos not included atm
        self.i_log.add(f"Ajout du produit {id_product}")
        gdr_cur.execute(f"SELECT {l_to_str(self.product_cols)} FROM Produit WHERE IDProduit={id_product}")
        gdr_con = gdr_cur.fetchone()
        if gdr_con is not None:
            gdr_prod = {}
            for v in range(len(gdr_con)):
                gdr_prod[self.product_cols[v]] = gdr_con[v]
            # Reqs can not be moved since gdr_prod needs to be set
            reqs = [
                (gdr_prod['Nombre'], ([0], False, "La quantité de ce produit est à 0")),
                (gdr_prod['IDSortie'], ([0, 1], True, "Ce produit ne peut pas être mis en vente"))
            ]
            if self.requirements(reqs) or self.debug.force_reqs:
                prod_exists = False
                for id_prod in self.get_indexes(('product', 'products')):
                    if self.api.get('products', id_prod)['product']['reference'] == str(id_product):
                        prod_exists = True
                        break  # opti
                if prod_exists and not self.debug.force_yes:
                    self.i_log.add(f"La référence {id_product} existe déjà dans la base de données")
                    yesno(self.frame, "Duplicata",
                          "La référence existe déjà dans la base de données, voulez-vous la mettre à jour?",
                          lambda: self.do_prod(id_product, title, cat_name, gdr_prod, True))
                else:
                    self.do_prod(id_product, title, cat_name, gdr_prod, prod_exists)
                self.i_log.add("Produit ajouté")
                return True
        else:
            self.i_log.add(f"ID {id_product} incorrecte")
        return False

    def do_prod(self, id_product, title, cat_name, gdr_prod, edit=False):
        """
        :param id_product: The IDProduit in GDR
        :type id_product: int
        :type title: str
        :type cat_name: str
        :param gdr_prod: {title : field} of the Produit table in HDR
        :type gdr_prod: dict
        :param edit: if the object is edited or simply added
        :return: The JSON response when the product was added
        :rtype: dict
        """
        # Ajout ou non de catégorie
        cat_exists = self.x_exists(('category', 'categories'), 'name', cat_name)
        id_cat = cat_exists[1]
        if cat_exists[0]:
            self.i_log.add("Catégorie trouvée")
        else:
            self.i_log.add(f"Ajout {cat_name}")
            id_cat = self.add_cat(cat_name)['id']
            self.i_log.add(f"Catégorie ajoutée")

        # Ajout produit
        date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        prod_schema = self.api.get('products', options={'schema': 'blank'})['product']
        prod_dict = {
            'id_category_default': f"{id_cat}",
            'id_shop_default': f"{1}",
            'reference': f"{id_product}",
            'width': f"{gdr_prod['Largeur']}",
            'height': f"{gdr_prod['Hauteur']}",
            'depth': f"{gdr_prod['Profondeur']}",
            'weight': f"{gdr_prod['Poids']}",
            'state': f"{1}",
            'minimal_quantity': f"{1}",
            'price': f"{float(gdr_prod['PrixUnitaire'])}",
            'wholesale_price': f"{int(gdr_prod['PrixUnitaire']) * int(gdr_prod['Nombre'])}",
            'active': f"{1}",
            'redirect_type': f"'301-product'",
            'available_for_order': f"{1}",
            'show_condition': f"{1}",
            'show_price': f"{1}",
            'condition': f"refurbished",
            'date_add': f"{date}",
            'date_upd': f"{date}"
        }
        prod_schema = {**prod_schema, **prod_dict}
        link_rewrite = cat_name.lower().encode("ascii", "ignore").decode("utf-8")
        self.set_lang(prod_schema, 'link_rewrite', link_rewrite)
        self.set_lang(prod_schema, 'name', title)
        # Association des catégories au produit
        prod_schema['associations']['categories']['category'] = [{'id': '2'}, {'id': f"{id_cat}"}]
        # Edit de l'objet si exigé
        if edit:
            p_idx = self.get_indexes(('product', 'products'))
            i = len(p_idx)
            for i in p_idx:
                curr_prod = self.api.get('products', i)['product']
                if curr_prod['reference'] == str(id_product):
                    break
            prod_schema['id'] = i
            p_act = self.api.edit
        else:
            p_act = self.api.add
        last_prod = p_act('products', {'product': prod_schema})['prestashop']['product']

        # Ajout image
        self.i_log.add("Ajout image")
        if self.do_img(id_product, last_prod['id']):
            self.i_log.add("Image ajoutée")

        # Ajout quantité
        sa_schema = self.api.get('stock_availables', options={'schema': 'blank'})['stock_available']
        prod_asc = last_prod['associations']
        sa_dict = {
            'id': f"{prod_asc['stock_availables']['stock_available']['id']}",
            'id_product': f"{last_prod['id']}",
            'id_product_attribute': f"{prod_asc['stock_availables']['stock_available']['id_product_attribute']}",
            'id_shop': f"{1}",
            'quantity': f"{gdr_prod['Nombre']}",
            'depends_on_stock': f"{0}",
            'out_of_stock': f"{2}"
        }
        sa_schema = {**sa_schema, **sa_dict}
        self.api.edit('stock_availables', {'stock_available': sa_schema})
        return last_prod

    def do_img(self, id_prod, ps_id_prod):
        cur_gdr = self.gdr_db.DB.cursor()
        cur_gdr.execute(f"SELECT Photo FROM Produit WHERE IDProduit={id_prod}")
        gdr_con = cur_gdr.fetchall()
        if len(gdr_con[0]) > 0:
            photo = bytes(gdr_con[0][0])
            files = {'image': (f"image-{1}.png", photo)}
            img_url = f"{self.ip}/api/images/products/{ps_id_prod}"
            # debug = requests.get(img_url, auth=HTTPBasicAuth(self.key, ''))
            return requests.post(img_url, files=files, auth=HTTPBasicAuth(self.key, ''))
        else:
            self.i_log.add("Image non trouvée")
            return False

    def add_cat(self, cat):
        """
        :param cat: The name of the category to add
        :type cat: str
        :return: The JSON response when the category was added
        """
        cat_schema = self.api.get('categories', options={'schema': 'blank'})['category']
        date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        cat_dict = {
            'id_parent': f"{2}",
            'active': f"{1}",
            'position': f"{0}",
            'date_add': f"{date}",
            'date_upd': f"{date}",
        }
        cat_schema = {**cat_schema, **cat_dict}
        self.set_lang(cat_schema, 'name', cat)
        link_rewrite = cat.lower().encode("ascii", "ignore").decode("utf-8")
        self.set_lang(cat_schema, 'link_rewrite', link_rewrite)
        return self.api.add('categories', {'category': cat_schema})['prestashop']['category']

    def sync_ventes(self):
        gdr_cur = self.gdr_db.DB.cursor()
        self.i_log.add("Synchronisation des ventes")
        for id_prod in self.get_indexes(('product', 'products')):
            nvc = rev_col(self.ventes_cols)
            reference = self.api.get('products', id_prod)['product']['reference']
            gdr_cur.execute(
                f"SELECT {l_to_str(self.ventes_cols)} FROM Lignes_Vente WHERE IDProduit={reference}")
            sells = gdr_cur.fetchall()
            for s1 in sells:
                ex_sum = 0
                for s2 in sells:
                    if s1[nvc['IDProduit']] == s2[nvc['IDProduit']]:
                        ex_sum += s2[nvc['Montant']]
                if ex_sum >= 0 and self.x_exists(('product', 'products'), 'reference', reference)[0]:
                    # Modification produit
                    prod_schema = self.api.get('products', id_prod)['product']
                    prod = {
                        'on_sale': f"{0}",
                        'active': f"{0}",
                        'available_for_order': f"{0}"
                    }
                    prod_schema = {**prod_schema, **prod}
                    # Those two attributes are not writable
                    prod_schema.pop('manufacturer_name')
                    prod_schema.pop('quantity')
                    # The position in category is sometimes over evaluated
                    pos_cat = int(prod_schema['position_in_category']['value'])
                    if pos_cat > 0:
                        pos_cat -= 1
                    prod_schema['position_in_category']['value'] = f"{pos_cat}"

                    last_prod = self.api.edit('products', {'product': prod_schema})['prestashop']['product']

                    # Modification quantité
                    sa_schema = self.api.get('stock_availables', int(
                        last_prod['associations']['stock_availables']['stock_available']['id']))[
                        'stock_available']
                    sa = {
                        'quantity': f"{0}",
                        'out_of_stock': f"{1}"
                    }
                    sa_schema = {**sa_schema, **sa}
                    self.api.edit('stock_availables', {'stock_available': sa_schema})
                    self.i_log.add(f"{id_prod} mis à jour")
        self.i_log.add("Images synchronisées")

    def set_lang(self, schema, key, name):
        """
        Sets the name in 2 languages e.g English and French
        :param schema: The schema you're inserting the lang into
        :type schema: dict
        :param key: Key where the language is situated
        :type key: str
        :param name: The name that'll be displayed, the same in the 2 languages
        :type name: str
        :return: The schema now modified
        :rtype: dict
        """
        # e.g. key : {'language': [{'attrs': {'id': '1'}, 'value': name}, {'attrs': {'id': '2'}, 'value': name}]}
        try:
            klang = schema[key]['language']
            if isinstance(klang, dict):
                klang['value'] = name
            else:  # if there is more than one lang
                for lang in klang:
                    lang['value'] = name
            return schema
        except KeyError:
            schema[key] = {'language': [{'attrs': {'id': f"{idl}"}, 'value': ''} for idl in
                                        self.get_indexes(('language', 'languages'))]}
            return self.set_lang(schema, key, name)

    def reset_db(self):
        """
        Only resets products and categories
        """
        prods = self.get_indexes(('product', 'products'))
        if prods:
            self.i_log.add("Suppression des produits")
            self.api.delete('products', prods)
            self.i_log.add("Produits supprimés")
        cats = self.get_indexes(('category', 'categories'))[2:]
        if cats:
            self.i_log.add("Suppression des catégories")
            self.api.delete('categories', cats)
            self.i_log.add("Catégories supprimées")
        # stock_available n'est pas deletable

    def x_exists(self, head_name, x, name):
        """
        Check if the name exists in the objects list
        :param head_name: singular[0], plural[1]
        :type head_name: tuple
        :param x: The column you're looking into
        :type x: str
        :type name: str
        :return: [0] : exists?, [1]: where in the list
        :rtype: tuple
        """
        hid = 0
        for hid in self.get_indexes(head_name):
            col = self.api.get(head_name[1], hid)[head_name[0]][x]
            if isinstance(col, dict):
                try:
                    if col['language'][0]['value'] == name:
                        return True, hid
                except KeyError:
                    if col['language']['value'] == name:
                        return True, hid
            if col == name:
                return True, hid
        return False, hid

    def get_indexes(self, head_name):
        """
        Get all indexes for the head_name
        :param head_name: singular[0], plural[1]
        :type head_name: tuple
        :rtype: list
        """
        head = self.api.get(head_name[1])[head_name[1]]
        if head != '':
            hh = head[head_name[0]]
            if not isinstance(hh, dict):
                return [int(attr['attrs']['id']) for attr in hh]
            return [int(hh['attrs']['id'])]
        return []