Site du proximo, utilisé pour gérer le stock.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

zapette.py 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. # run pip3 install requests
  2. import requests
  3. import json
  4. import os
  5. from signal import signal, SIGINT
  6. from sys import exit
  7. # API_ENDPOINT = "https://etud.insa-toulouse.fr/~proximo/ajax/zapette.php"
  8. API_ENDPOINT = "http://localhost/proximo/ajax/zapette.php"
  9. class bcolors:
  10. HEADER = '\033[95m'
  11. OKBLUE = '\033[94m'
  12. OKGREEN = '\033[92m'
  13. WARNING = '\033[93m'
  14. FAIL = '\033[91m'
  15. ENDC = '\033[0m'
  16. BOLD = '\033[1m'
  17. UNDERLINE = '\033[4m'
  18. class scan_types:
  19. SELL = 'v',
  20. BUY = 'a',
  21. class error_types:
  22. NONE = 0,
  23. NETWORK = 1,
  24. URL = 2,
  25. INPUT = 3,
  26. NO_EXIST = 4,
  27. class Scanner:
  28. def __init__(self):
  29. self.ask_type()
  30. self.password = self.get_password()
  31. self.scannedArticles = []
  32. def ask_type(self):
  33. typeInput = input("\nVoulez vous " + bcolors.OKGREEN + "acheter" + bcolors.ENDC + " ou " + bcolors.FAIL + "vendre" + bcolors.ENDC + " ? [" + bcolors.OKGREEN + "a" + bcolors.ENDC + "/" + bcolors.FAIL + "v" + bcolors.ENDC + "] ")
  34. if (typeInput.lower() == 'a'):
  35. self.type = scan_types.BUY
  36. else:
  37. self.type = scan_types.SELL
  38. def get_password(self):
  39. with open('pass') as f:
  40. password = f.readline()
  41. return password.strip()
  42. def display_type(self):
  43. if (self.type == scan_types.SELL):
  44. print(" ==> Mode " + bcolors.FAIL + bcolors.BOLD + "VENTE")
  45. else:
  46. print(" ==> Mode " + bcolors.OKGREEN + bcolors.BOLD + "ACHAT")
  47. print(bcolors.ENDC)
  48. def scan_product(self, code):
  49. data = {
  50. 'password': self.password,
  51. 'action': 'scan',
  52. 'data': str(code)
  53. }
  54. r = requests.post(url=API_ENDPOINT, data=json.dumps(data))
  55. if (r.json()['status'] == 0):
  56. article = r.json()["data"]
  57. self.scannedArticles.append(article)
  58. return r.json()['status'] == 0
  59. def display_cart(self):
  60. total = 0.0
  61. for article in self.scannedArticles:
  62. print(article["name"] + ' : ' + bcolors.BOLD + article["price"] + '€' + bcolors.ENDC)
  63. total += float(article["price"])
  64. # Print only to only 2 decimals
  65. total_display = "{:.2f}".format(total)
  66. print(bcolors.OKGREEN + "Total: " + bcolors.BOLD + total_display + '€' + bcolors.ENDC)
  67. def send_cart(self):
  68. scanned_list = []
  69. modifier = -1 if self.type == scan_types.SELL else 1
  70. for article in self.scannedArticles:
  71. scanned_list.append({"id": article["id"], "quantity": modifier})
  72. data = {
  73. 'password': self.password,
  74. 'action': 'validate',
  75. 'data': scanned_list
  76. }
  77. r = requests.post(url=API_ENDPOINT, data=json.dumps(data))
  78. return r.json()['status'] == 0
  79. def ask_confirmation(message):
  80. confirm_input = input(message)
  81. return confirm_input.lower() == 'o'
  82. def clear_screen():
  83. os.system('clear')
  84. print("Appuyez sur " + bcolors.BOLD + "[CTRL + C]" + bcolors.ENDC + " à tout moment pour quitter.\n")
  85. def printStartScreen():
  86. clear_screen()
  87. print(bcolors.BOLD)
  88. print(bcolors.WARNING + "#########################################")
  89. print("#/ \#")
  90. print("# " + bcolors.FAIL + "-=|" + bcolors.OKGREEN + " ZAPETTE " + bcolors.FAIL + "|=-" + bcolors.WARNING + " #")
  91. print("#\ /#")
  92. print("#########################################")
  93. print(bcolors.ENDC)
  94. print("Bienvenue dans le programme de la Zapette !")
  95. def display_scan_header(scanner, last_error):
  96. clear_screen()
  97. scanner.display_type()
  98. print("Scannez le codes puis appuyez sur [ENTRÉE] pour valider.")
  99. print("Appuyez sur [ENTRÉE] sans code pour valider la commande.\n")
  100. scanner.display_cart()
  101. if (last_error == error_types.URL):
  102. print(bcolors.FAIL + "Format URL invalide !" + bcolors.ENDC)
  103. elif (last_error == error_types.NETWORK):
  104. print(bcolors.FAIL + "URL invalide !" + bcolors.ENDC)
  105. elif (last_error == error_types.INPUT):
  106. print(bcolors.FAIL + "Code invalide !" + bcolors.ENDC)
  107. elif (last_error == error_types.NO_EXIST):
  108. print(bcolors.FAIL + "L'article n'existe pas." + bcolors.ENDC)
  109. print()
  110. def confirm_end_scan(scanner):
  111. display_scan_header(scanner, error_types.NONE)
  112. return ask_confirmation("Voulez vous vraiment terminer et envoyer les modifications ? [o/n] ")
  113. def handler(signal_received, frame):
  114. os.system('clear')
  115. print('Programme de la zapette terminé.')
  116. exit(0)
  117. def validate_cart(scanner):
  118. clear_screen()
  119. print("Envoi des modifications au serveur...")
  120. if (scanner.send_cart()):
  121. print(bcolors.OKGREEN + bcolors.BOLD + "Succès !" + bcolors.ENDC)
  122. else:
  123. print(bcolors.FAIL + bcolors.BOLD + "Échec !" + bcolors.ENDC)
  124. input("\nAppuyez sur [ENTRÉE] pour continuer...")
  125. def main():
  126. signal(SIGINT, handler)
  127. printStartScreen()
  128. while True:
  129. scanner = Scanner()
  130. last_error = error_types.NONE
  131. while True:
  132. display_scan_header(scanner, last_error)
  133. code_input = input('=> ')
  134. if (code_input == ""):
  135. if (confirm_end_scan(scanner)):
  136. validate_cart(scanner)
  137. break
  138. else:
  139. continue
  140. try:
  141. code = int(code_input)
  142. if (scanner.scan_product(code)):
  143. last_error = error_types.NONE
  144. else:
  145. last_error = error_types.NO_EXIST
  146. except requests.exceptions.MissingSchema:
  147. last_error = error_types.URL
  148. except requests.exceptions.ConnectionError:
  149. last_error = error_types.NETWORK
  150. except ValueError:
  151. last_error = error_types.INPUT
  152. clear_screen()
  153. main()