def search(self, filters=None): api = PrestaShopWebServiceDict(self.prestashop.api_url, self.prestashop.webservice_key) res = api.get(self._prestashop_model, options=filters) methods = res[self._prestashop_model][self._export_node_name] if isinstance(methods, dict): return [methods] return methods
def export_quantity_url(self, url, key, filters, quantity): api = PrestaShopWebServiceDict(url, key) response = api.search(self._prestashop_model, filters) for stock_id in response: res = api.get(self._prestashop_model, stock_id) first_key = res.keys()[0] stock = res[first_key] stock['quantity'] = int(quantity) try: api.edit(self._prestashop_model, {self._export_node_name: stock}) except ElementTree.ParseError: pass
def export_quantity_url(self, url, key, filters, quantity): api = PrestaShopWebServiceDict(url, key) response = api.search(self._prestashop_model, filters) for stock_id in response: res = api.get(self._prestashop_model, stock_id) first_key = res.keys()[0] stock = res[first_key] stock['quantity'] = int(quantity) try: api.edit(self._prestashop_model, { self._export_node_name: stock }) except ElementTree.ParseError: pass
from __future__ import print_function from prestapyt import PrestaShopWebServiceDict from xml.etree import ElementTree prestashop = PrestaShopWebServiceDict('http://localhost:8080/api', 'BVWPFFYBT97WKM959D7AVVD0M4815Y1L',) 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',
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
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 []