def liste(product_list, Config): clean() # Si le nombre de produits et supérieur à la taille du CMD, on ajoute une scroll bar if len(product_list) >= 32: handle = windll.kernel32.GetStdHandle(-11) buffsize = int(18 + len(product_list)) bufsize = wintypes._COORD(92, buffsize) windll.kernel32.SetConsoleScreenBufferSize(handle, bufsize) # Liste les produits disponible sous forme de tableau ascii print(Style.DIM + Fore.YELLOW + (Config.name).center(92) + Style.RESET_ALL) print(("¯" * len(Config.name)).center(92)) print("==== Produits Disponibles ({}) ====\n".format( len([f for f in product_list])).center(50)) rows = [] for elt, content_file in enumerate(sorted(product_list)): headers = ["Id", "Nom", "Prix"] rows.append([ Style.BRIGHT + "[" + Fore.RED + str(elt) + Fore.WHITE + "]", Style.DIM + Fore.YELLOW + content_file[0], Fore.WHITE + content_file[2] + " " + Fore.CYAN + content_file[3] + Style.RESET_ALL, ]) print(tabulate(rows, headers=headers, tablefmt="rst")) print("\n") # Selection du produit voulu. try: Choice = int(input("Choississez un produit (ID): " + Fore.YELLOW)) print(Style.RESET_ALL) if Choice >= len([f for f in product_list]): raise Exception("Invalid number") for elt, product in enumerate(sorted(product_list)): if elt == Choice: product_info(product, Config) break except Exception as e: print(Style.RESET_ALL) clean() print(e) print(Style.BRIGHT + Fore.RED + "[ ERROR ] Veuillez entrer un nombre valide".center(92) + Style.RESET_ALL) time.sleep(2) liste(product_list)
def run(map_substring, map_files): while True: user_input = input("Enter your text\n") if user_input == STOP_PROGRAM: break while True: if user_input[-1] == STOP_INPUT: break auto_complete_best_options = get_best_k_completions( clean(user_input), map_substring, map_files) if not auto_complete_best_options: print(f"no suggestions for {user_input}") break for i, auto_complete_option in enumerate( auto_complete_best_options, 1): print(f"{i}:{auto_complete_option}") user_input += input(user_input)
def product_info(product, Config): try: clean() print("[ INFO ] En recherche de coupons...".center(92) + "\n") # Récupères le coupons coupons = Fetch_Coupons(Config.name) clean() # Liste les infos sur le produit print( Style.DIM + Fore.YELLOW + "Informations sur le produit" + Style.RESET_ALL + "\n¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯" ) print("Titre: " + Fore.YELLOW + product[0] + Style.RESET_ALL) print("\n") print("Prix: " + product[2] + Fore.CYAN + " " + product[3] + Style.RESET_ALL) print("\n") print("Url: " + Fore.YELLOW + product[1] + Style.RESET_ALL) print("\n") if coupons is None: len_coupons = 0 else: len_coupons = len(coupons) print( "Nombre de coupons trouvés: " + Fore.YELLOW + str(len_coupons) + Style.RESET_ALL ) print("\n") print( "Que voudriez-vous faire?:\n¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n" + "[" + Fore.RED + "1" + Style.RESET_ALL + "] " + Fore.GREEN + "Afficher les coupons" + Style.RESET_ALL + "\n[" + Fore.RED + "2" + Style.RESET_ALL + "] " + Fore.GREEN + "Vérifier le solde d'une carte cadeau/coupon" + Style.RESET_ALL + "\n[" + Fore.RED + "3" + Style.RESET_ALL + "] " + Fore.RED + "Retourner au menu" + Style.RESET_ALL ) try: choice = int( input("[" + Fore.CYAN + "→" + Style.RESET_ALL + "] " + Fore.YELLOW) ) except Exception: print(Style.RESET_ALL) clean() print( Style.BRIGHT + Fore.RED + "[ ERROR ] Veuillez entrer un nombre".center(92) + Style.RESET_ALL ) time.sleep(2) product_info(product, Config) if int(choice) < 1 or int(choice) > 3: clean() print( Style.BRIGHT + Fore.RED + "[ ERROR ] Veuillez choisir une des options".center(92) + Style.RESET_ALL ) time.sleep(2) product_info(product, Config) # Liste les codes de réduction if int(choice) == 1: if coupons is None: clean() print( Style.BRIGHT + Fore.RED + "[ ERROR ] Aucun coupon disponible".center(92) + Style.RESET_ALL ) time.sleep(3) product_info(product, Config) else: clean() print(Style.DIM + Fore.YELLOW + (Config.name).center(92) + Style.RESET_ALL) print(("¯" * len(Config.name)).center(92)) print( "==== Coupons Disponibles ({}) ====\n".format( len([f for f in coupons]) ).center(30) ) rows = [] for elt, content_file in enumerate(sorted(coupons)): headers = ["Id", "Code du coupon", "Discount/Valeur"] rows.append( [ Style.BRIGHT + "[" + Fore.RED + str(elt) + Fore.WHITE + "]", Style.DIM + Fore.YELLOW + content_file[0], Fore.GREEN + content_file[1] + Style.RESET_ALL, ] ) print(tabulate(rows, headers=headers, tablefmt="rst")) print("\n" * 2) print( "Appuyez sur Entrée pour continuer\n¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯" ) input() product_info(product, Config) # Vérifie le sole d'un coupon ou d'une carte cadeau elif int(choice) == 2: clean() print( "Veuillez entrer un code de carte cadeau ou un coupon:\n¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯" ) try: code = input( "[" + Fore.CYAN + "→" + Style.RESET_ALL + "] " + Fore.YELLOW ) except Exception: print(Style.RESET_ALL) clean() print( Style.BRIGHT + Fore.RED + "[ ERROR ] Veuillez entrer un code valide".center(92) + Style.RESET_ALL ) time.sleep(2) product_info(product, Config) Check_Balance(code, Config) # Retourne à la sélection de site Shopify elif int(choice) == 3: pass except Exception as e: print(Style.RESET_ALL) clean() print( Style.BRIGHT + Fore.RED + "[ ERROR ] Une erreur s'est produite: ".center(92) + "\n" + str(e).center(92) + Style.RESET_ALL ) time.sleep(2)
def Fetch_Coupons(Name): try: # En cas d'erreur HTTP, renvoyer la requête session = requests.Session() retries = Retry( total=5, backoff_factor=0.1, status_forcelist=[500, 502, 503, 504, 408] ) session.mount("https://", HTTPAdapter(max_retries=retries)) # Utilise l'API de recherche de promocodes.com pour chercher le nom du site Shopify fetch_url = session.get( f"https://www.promocodes.com/search?term={Name}", verify=False, allow_redirects=True, ) try: url = fetch_url.json()["MerchantMatches"][0]["Url"] try: # Envoie une requête à la page promocodes.com du site shopify fetch_codes = session.get( f"https://www.promocodes.com{url}", verify=False, allow_redirects=True, ) root = html.fromstring(fetch_codes.text) # Scrap les IDs des codes promos coupon_ids = [] for item in root.xpath( '//*[@class="coupon-cta btn btn-main-outline"]/@data-coupon-id' ): coupon_ids.append(item) for item in root.xpath( '//*[@class="coupon-cta btn btn-main-outline js-coupon-modal"]/@data-coupon-id' ): coupon_ids.append(item) try: coupons = [] # Récupères les codes promos à l'aide des IDs for item in coupon_ids: try: get_coupon = session.get( "https://www.promocodes.com/couponmodals/coupon", params={"couponId": item}, ) except Exception as e: print(e) pass if "No promo code needed" in get_coupon.text: pass else: root = html.fromstring(get_coupon.text) coupon = root.xpath( '//*[@class="coupon-modal-code"]/text()' )[0] discount = root.xpath( '//*[@class="coupon-headline-savings"]/text()' )[0] coupons.append([coupon, discount]) except Exception as e: print(Style.RESET_ALL) clean() print( Style.BRIGHT + Fore.RED + "[ ERROR ] Une erreur s'est produite:".center(92) + "\n" + str(e).center(92) + Style.RESET_ALL ) time.sleep(3) coupons = None except Exception as e: print(Style.RESET_ALL) clean() print( Style.BRIGHT + Fore.RED + "[ ERROR ] Une erreur s'est produite:".center(92) + "\n" + str(e).center(92) + Style.RESET_ALL ) time.sleep(3) coupons = None except Exception as e: print(Style.RESET_ALL) clean() print( Style.BRIGHT + Fore.RED + "[ ERROR ] Une erreur s'est produite:".center(92) + "\n" + str(e).center(92) + Style.RESET_ALL ) time.sleep(3) coupons = None except Exception as e: print(Style.RESET_ALL) clean() print( Style.BRIGHT + Fore.RED + "[ ERROR ] Une erreur s'est produite:".center(92) + "\n" + str(e).center(92) + Style.RESET_ALL ) time.sleep(3) coupons = None return coupons
def URL(): while True: Window_setting() clean() # Demande l'URL du site shopify à scrap try: print("Entrez l'URL Shopify (avec https://):".center(92)) print("¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯".center(92)) shopifyurl = input( "\n".center(45) + "[" + Fore.CYAN + "→" + Style.RESET_ALL + "] " + Fore.YELLOW ) except Exception: print(Style.RESET_ALL) clean() print( Style.BRIGHT + Fore.RED + "[ ERROR ] Veuillez entrer une URL valide".center(92) + Style.RESET_ALL ) time.sleep(2) URL() # Vérifie via regex que le format de l'url est valide if ( len( re.findall( r"(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?", shopifyurl, ) ) <= 0 ): clean() print( Style.BRIGHT + Fore.RED + "[ ERROR ] Veuillez entrer une URL valide (vous devez inclure le https://)".center( 92 ) + Style.RESET_ALL ) time.sleep(4) URL() clean() print("[ INFO ] En recherche de produits...".center(92) + "\n") try: try: # En cas d'erreur HTTP, renvoyer la requête session = requests.Session() retries = Retry( total=5, backoff_factor=0.1, status_forcelist=[500, 502, 503, 504, 408], ) session.mount("https://", HTTPAdapter(max_retries=retries)) # Récupères en liste des produits du site r = session.get( url=shopifyurl + "/collections/all/products.atom", verify=False, allow_redirects=True, ) if r.status_code != 200: raise Exception except Exception: try: r = session.get(url=shopifyurl, verify=False) # Vérifie que le site est bien un site Shopify if "shopify-features" in r.text: clean() print( Style.BRIGHT + Fore.RED + "[ ERROR ] La collection du site est indisponible. Veuillez entrer".center( 92 ) + "\n" + "uniquement l'index du site et non pas l'url d'un produit".center( 92 ) + Style.RESET_ALL ) time.sleep(4) URL() else: clean() print( Style.BRIGHT + Fore.RED + "[ ERROR ] L'url que vous avez entré ne semble pas être un site shopify".center( 92 ) + "\n" + "veuillez essayer une autre url".center(92) + Style.RESET_ALL ) time.sleep(4) URL() except Exception: clean() print( Style.BRIGHT + Fore.RED + "[ ERROR ] Site web indisponible. Veuillez verifier votre connection internet".center( 92 ) + "\n" + "et verifier que l'url est valide (avec https://)".center(92) + Style.RESET_ALL ) time.sleep(4) URL() # Scrap les infos utiles des produits bs = soup(r.text, "html.parser") shoptitle = bs.select_one("title").text products = [] for allProducts in bs.find_all("entry"): if len(allProducts) == 0: print(Style.RESET_ALL) clean() print( Style.BRIGHT + Fore.RED + "[ ERROR ] Aucun produit trouvé, veuillez verifier que l'url est valide et que le site ai au moins un item.".center( 92 ) + Style.RESET_ALL ) time.sleep(3) URL() for product in allProducts.find("title"): # Nettoie les balises HTML des titres de produits cleaned = re.compile('<.*?>') productTitle = re.sub(cleaned, '', product) productLink = product.parent.parent.find("link")["href"] price = product.parent.parent.find("s:price").text currency = product.parent.parent.find("s:price")["currency"] products.append([productTitle, productLink, price, currency]) clean() # Récap que le site est bien le bon print( Fore.YELLOW + "".center(34) + "Titre du magasin: " + Fore.WHITE + shoptitle + Style.RESET_ALL + "\n" ) print( "Cette information est-elle correcte?\n¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\n" + "[" + Fore.RED + "1" + Style.RESET_ALL + "] " + Fore.GREEN + "OUI" + Style.RESET_ALL + "\n[" + Fore.RED + "2" + Style.RESET_ALL + "] " + Fore.GREEN + "NON" + Style.RESET_ALL ) try: validity = int( input("[" + Fore.CYAN + "→" + Style.RESET_ALL + "] " + Fore.YELLOW) ) except Exception: print(Style.RESET_ALL) clean() print( Style.BRIGHT + Fore.RED + "[ ERROR ] Veuillez entrer un nombre".center(92) + Style.RESET_ALL ) time.sleep(2) URL() if int(validity) < 1 or int(validity) > 2: clean() print( Style.BRIGHT + Fore.RED + "[ ERROR ] Veuillez choisir une des options".center(92) + Style.RESET_ALL ) time.sleep(2) URL() if int(validity) == 1: try: # Récupères des données pour l'éventuelle checkout d'un produit response = session.get(products[0][1], verify=False) bs = soup(response.text, "html.parser") scripts = bs.findAll("script") jsonObj = None for s in scripts: if "var meta" in s.text: script = s.text script = script.split("var meta = ")[1] script = script.split(";\nfor (var attr in meta)")[0] jsonStr = script jsonObj = json.loads(jsonStr) for value in jsonObj["product"]["variants"]: VariantPrice = int(value["price"]) / 100 variantID = value["id"] break except Exception: try: response = session.get(products[0][1], verify=False) bs = soup(response.text, "html.parser") scripts = bs.findAll("script") jsonObj = None for s in scripts: if "var meta" in s.text: script = s.text script = script.split("var meta = ")[1] script = script.split(";\nfor (var attr in meta)")[0] jsonStr = script jsonObj = json.loads(jsonStr) for value in jsonObj["product"]["variants"]: VariantPrice = int(value["price"]) / 100 variantID = value["id"] break except Exception as e: print(Style.RESET_ALL) clean() print( Style.BRIGHT + Fore.RED + "[ ERROR ] Une erreur s'est produite:".center(92) + "\n" + str(e).center(92) + Style.RESET_ALL ) time.sleep(3) URL() Config = Data() Config.name = shoptitle Config.link = r.url.replace("/collections/all/products.atom", "") Config.currency = products[0][3] Config.productid = variantID Config.price = VariantPrice liste(products, Config) elif int(validity) == 2: URL() except Exception as e: print(Style.RESET_ALL) clean() print( Style.BRIGHT + Fore.RED + "[ ERROR ] Une erreur s'est produite:".center(92) + "\n" + str(e).center(92) + Style.RESET_ALL ) time.sleep(3) URL()
def Check_Balance(Code, Config): # Ajoute un item au panier clean() print("[ INFO ] En cours de checkout...".center(92) + "\n") session = requests.Session() retries = Retry(total=5, backoff_factor=0.1, status_forcelist=[500, 502, 503, 504, 408]) session.mount("https://", HTTPAdapter(max_retries=retries)) link = "%s/cart/add.js?quantity=1&id=%s" % (Config.link, str(Config.productid)) try: session.get(link, verify=False, allow_redirects=True) except Exception: try: session.get(link, verify=False, allow_redirects=True) except Exception as e: print(Style.RESET_ALL) clean() print(Style.BRIGHT + Fore.RED + "[ ERROR ] Une erreur s'est produite:".center(92) + "\n" + str(e).center(92) + Style.RESET_ALL) # Passe au checkout tempLink = "%s//checkout.json" % Config.link try: response = session.get(tempLink, verify=False, allow_redirects=True) except Exception: try: time.sleep(5) response = session.get(tempLink, verify=False, allow_redirects=True) except Exception as e: print(Style.RESET_ALL) clean() print(Style.BRIGHT + Fore.RED + "[ ERROR ] Une erreur s'est produite:".center(92) + "\n" + str(e).center(92) + Style.RESET_ALL) time.sleep(3) # Scrap de données et mises en place des paramètres de checkout tree = html.fromstring(response.text) authToken = tree.xpath('//*[@name="authenticity_token"]/@value')[0] checkout = response.url _landing_page = response.url.replace(Config.link, "") _orig_referrer = Config.link + "/cart" checkoutLink = checkout.replace(Config.link, "https://checkout.shopify.com") # Placeholder des cookies _secure_session_id = "null" checkout_token_cookie = "null" checkout_cookie = "null" _shopify_s = "null" _shopify_y = "null" _shopify_fs = datetime.datetime.utcnow().strftime( "%Y-%m-%dT%H:%M:%S.%f")[:-3] + "Z" tracked_start_checkout = "null" checkout_locale = "en" for cookie in response.cookies: if cookie.name == "checkout": checkout_cookie = cookie.value elif cookie.name == "checkout_token": checkout_token_cookie = cookie.value elif cookie.name == "_secure_session_id": _secure_session_id = cookie.value elif cookie.name == "_shopify_y": _shopify_y = cookie.value elif cookie.name == "_shopify_s": _shopify_s = cookie.value elif cookie.name == "tracked_start_checkout": tracked_start_checkout = cookie.value elif cookie.name == "checkout_locale": checkout_locale = cookie.value time.sleep(0.8) _shopify_sa_t = ( datetime.datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + "Z") # Mise en place des cookies de la requête request_cookies = { "_landing_page": _landing_page, "_orig_referrer": _orig_referrer, "_s": _shopify_s, "_secure_session_id": _secure_session_id, "_shopify_fs": _shopify_fs, "_shopify_s": _shopify_s, "_shopify_sa_p": "", "_shopify_sa_t": _shopify_sa_t, "_shopify_y": _shopify_y, "cart_sig": "", "checkout": checkout_cookie, "checkout_locale": checkout_locale, "checkout_token": checkout_token_cookie, "secure_customer_sig": "", "test_cookie": "", "tracked_start_checkout": tracked_start_checkout, } browser_width = str(random.randint(1080, 2046)) browser_height = str(random.randint(720, 1080)) ts = time.time() utc_offset = round( (datetime.datetime.fromtimestamp(ts) - datetime.datetime.utcfromtimestamp(ts)).total_seconds() / 60) # Paramètres data pour la requête POST params = { "_method": "patch", "authenticity_token": authToken, "step": "contact_information", "checkout[reduction_code]": Code, "checkout[client_details][browser_width]": browser_width, "checkout[client_details][browser_height]": browser_height, "checkout[client_details][javascript_enabled]": "1", "checkout[client_details][color_depth]": "24", "checkout[client_details][java_enabled]": "false", "checkout[client_details][browser_tz]": utc_offset, } # Applique le code carte cadeau/coupon au produit try: check = requests.post(checkoutLink, cookies=request_cookies, data=params, allow_redirects=True) except Exception: try: check = requests.post(checkoutLink, cookies=request_cookies, data=params, allow_redirects=True) except Exception: check = None clean() print(Style.BRIGHT + "Résultats".center(92) + "\n" + "¯¯¯¯¯¯¯¯¯".center(92)) if check is None: print("La carte/code " + Fore.YELLOW + Code + Style.RESET_ALL + " n'est pas valide ou a une valeur nul") else: # Vérifie si la valeur du produit a changé tree = html.fromstring(check.text) price = (int( tree.xpath( '//*[@class="total-recap__final-price"]/@data-checkout-payment-due-target' )[0]) / 100) # Si oui on calcule la valeur du code/carte cadeau if float(price) != float(Config.price): balance = float(Config.price) - float(price) percentage = float(balance) / float(price) * 100 print("La carte/code " + Fore.YELLOW + Code + Style.RESET_ALL + " a une valeur de " + Fore.GREEN + str("{:.2f}".format(balance)) + " " + Style.DIM + Config.currency + Style.RESET_ALL + " (soit " + str("{:.2f}".format(percentage)) + "%)" + Style.RESET_ALL) # Si la valeur n'a pas changé, le code est invalide ou de valeur nul else: print("La carte/code " + Fore.YELLOW + Code + Style.RESET_ALL + " n'est pas valide ou a une valeur nul") print("\n" * 3) print( "Appuyez sur la touche Entrée pour continuer\n¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯" ) input()