Beispiel #1
1
 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 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
Beispiel #4
0
    def search(self, filters=None):
        result = super(SaleOrderAdapter, self).search(filters=filters)

        shop_ids = self.session.search(
            'prestashop.shop', [('backend_id', '=', self.backend_record.id)])
        shops = self.session.browse('prestashop.shop', shop_ids)
        for shop in shops:
            if not shop.default_url:
                continue

            api = PrestaShopWebServiceDict('%s/api' % shop.default_url,
                                           self.prestashop.webservice_key)
            result += api.search(self._prestashop_model, filters)
        return result
Beispiel #5
0
    def search(self, filters=None):
        result = super(SaleOrderAdapter, self).search(filters=filters)

        shop_ids = self.session.search('prestashop.shop', [
            ('backend_id', '=', self.backend_record.id)
        ])
        shops = self.session.browse('prestashop.shop', shop_ids)
        for shop in shops:
            if not shop.default_url:
                continue

            api = PrestaShopWebServiceDict(
                '%s/api' % shop.default_url, self.prestashop.webservice_key
            )
            result += api.search(self._prestashop_model, filters)
        return result
Beispiel #6
0
def connect(token: str):
    try:
        ps = PrestaShopWebServiceDict('https://caneva937.com/api', token)
        return ps
    except:
        print("[E] Errore collegamento a prestashop")
        exit(1)
 def external_connection(self,
                         cr,
                         uid,
                         id,
                         debug=False,
                         logger=False,
                         context=None):
     if isinstance(id, list):
         id = id[0]
     referential = self.browse(cr, uid, id, context=context)
     prestashop = PrestaShopWebServiceDict('%s/api' % referential.location,
                                           referential.apipass,
                                           debug=referential.debug)
     try:
         prestashop.head('')
     except PrestaShopAuthenticationError, e:
         if config['debug_mode']: raise
         raise osv.except_osv(
             _("Connection Error"),
             _("Could not connect to the PrestaShop webservice\nCheck the webservice URL and password\nHTTP error code: %s"
               % e.error_code))
 def connect(self):
     # Add parameter to debug
     # https://github.com/akretion/prestapyt/blob/master/prestapyt/prestapyt.py#L81
     _logger.info(
         "Connect to %s with apikey %s in debug mode %s and \
                     timeout %s", self.prestashop.api_url,
         self.prestashop.webservice_key, str(self.prestashop.api_debug),
         str(self.prestashop.api_timeout))
     return PrestaShopWebServiceDict(
         self.prestashop.api_url, self.prestashop.webservice_key,
         self.prestashop.api_debug, None,
         {'timeout': self.prestashop.api_timeout})
    def __init__(self, environment):
        """

        :param environment: current environment (backend, session, ...)
        :type environment: :py:class:`connector.connector.ConnectorEnvironment`
        """
        super(PrestaShopCRUDAdapter, self).__init__(environment)
        self.prestashop = PrestaShopLocation(
            self.backend_record.location.encode(),
            self.backend_record.webservice_key)
        self.client = PrestaShopWebServiceDict(
            self.prestashop.api_url,
            self.prestashop.webservice_key,
        )
Beispiel #10
0
    def export_quantity(self, filters, quantity):
        self.export_quantity_url(
            filters,
            quantity,
        )

        shops = self.env['prestashop.shop'].search([
            ('backend_id', '=', self.backend_record.id),
            ('default_url', '!=', False),
        ])
        for shop in shops:
            url = '%s/api' % shop.default_url
            key = self.backend_record.webservice_key
            client = PrestaShopWebServiceDict(url, key)
            self.export_quantity_url(filters, quantity, client=client)
Beispiel #11
0
    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"
Beispiel #12
0
 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
Beispiel #13
0
def main():
    prestashop = PrestaShopWebServiceDict(
        'http://efilmy.best/api',
        'AZ2A2PZC183CQIEHI8KR3SC48E8CTA7T',
    )
    while 1:
        print("1 Create Category Tree")
        print("2 Add features")
        print("3 Add products")
        print("4 Exit")
        x = input()
        if x == '1':
            create_category_tree(prestashop)
        elif x == '2':
            create_feature_tree(prestashop)
        elif x == '3':
            add_products(prestashop)
        elif x == '4':
            break
Beispiel #14
0
                'available_later': {
                    'language': {
                        'attrs': {
                            'id': '1'
                        },
                        'value': ''
                    }
                },
                'id_default_combination':
                ''
            })
            prestashop.add('products', data_schema)
            add_image(prod_id, prestashop, product[4].encode('utf8'))
            add_sizes(prestashop, product[6], prod_id)
            change_quantity(prod_id, prestashop)
            add_features(prestashop, product, prod_id)
            prod_id += 1


if __name__ == '__main__':
    api = PrestaShopWebServiceDict('http://localhost/prestashop/api',
                                   'FXZ7H2NRVH24PB2HH9NGTDD7C92KSFHE')

    df = pd.read_csv('categories.csv', header=None, encoding='utf8')
    df = [list(row) for row in df.values]
    import_categories(df, api)

    df = pd.read_csv('products.csv', header=None, encoding='utf8', sep=';')
    df = [list(row) for row in df.values]
    import_products(df, api)
#Woocomerce EXPORT
api_url = 'http://woocomercedomain.com/wp-json/wc/v1/products'
api_key = 'ck_xxxx'
api_secret = 'cs_xxxxxx'
products = get_woocomerce_products(api_url, api_key, api_secret)
# pprint(products)

# PRESTASHOP IMPORT

# For production PS
ps_token = 'XXXX'
protocol_url = 'https://'
ps_url_api = 'yourdomain.com/api'

prestashop = PrestaShopWebServiceDict('{}{}'.format(protocol_url, ps_url_api),
                                      ps_token)

seller_id = 4  # Particular Knowband Marketplace seller id
# Todo: insert the right categories matching from a table
category_id = 43  # Art and culture
id_shop = 1  # Prestashop shop general id

for p in products:
    url_img = ''

    if 'images' in p:
        for im in p['images']:
            if im['src']:
                url_img = im['src']

    # pprint(p)
Beispiel #16
0
 def connect(self):
     return PrestaShopWebServiceDict(self.prestashop.api_url,
                                     self.prestashop.webservice_key)
Beispiel #17
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
Beispiel #18
0
        # without shipping info, color
        f.write(
            u'{0}\t"{1}"\t"{2}"\t{3}\t{4}\t{5}\t{6}\t{7}\t{8}\t{9}\t{10}\t{11}\t{12}\n'
            .format(id, title, description, link, image_link, avail, price,
                    currency, gpc, brand, age_group, gender, condition))

    return


if __name__ == '__main__':

    try:
        basedir = sys.argv[1]
    except IndexError:
        basedir = '.'

    config = ConfigParser()
    config.read(basedir + '/config.ini')

    file = codecs.open(
        "{0}/{1}-{2}.tsv".format(config.get('report', 'folder_name'),
                                 config.get('report', 'file_name'),
                                 config.get('report', 'lang')), "w",
        "utf-8-sig")

    ps = PrestaShopWebServiceDict(config.get('ps', 'api_url'),
                                  config.get('ps', 'token'))

    get_fb_catalog(ps, file, config)

    file.close()
Beispiel #19
0
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',
Beispiel #20
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 []