diff --git a/database.py b/database.py index 112a76a..ac8c6a1 100644 --- a/database.py +++ b/database.py @@ -1,5 +1,5 @@ import pymysql -import os, csv +import os, csv, time class db(): _requetes = { @@ -15,7 +15,7 @@ class db(): "selectAuteurByPrenom" : "SELECT * FROM `Auteur` WHERE `Prénom` LIKE %s ORDER BY `ID` ASC;", "selectAuteurByAlias" : "SELECT * FROM `Auteur` WHERE `Alias` LIKE %s ORDER BY `ID` ASC;", "selectPointDeVenteByNom" : "SELECT * FROM `Point de vente` WHERE `Nom` LIKE %s;", - "selectPointDeVenteByAdresse" : "SELECT Nom FROM `Point de vente` WHERE `Adresse` LIKE %s;", + "selectPointDeVenteByAdresse" : "SELECT * FROM `Point de vente` WHERE `Adresse` LIKE %s;", "selectLivreByISBN" : "SELECT * FROM `Livre` WHERE `ISBN` LIKE %s;", "selectLivreByTitre" : "SELECT * FROM `Livre` WHERE `Titre` LIKE %s;", "selectLivreByAuteurNom" : "SELECT * FROM Livre JOIN Auteur ON Livre.Auteur = Auteur.ID WHERE Auteur.Nom LIKE %s", @@ -39,6 +39,7 @@ class db(): "selectISBNAllLivres" : "SELECT ISBN FROM `Livre`;", "selectPointDeVenteNameByAdresse" : "SELECT Nom FROM `Point de vente` WHERE `Adresse` = %s;", "selectUserByEmail" : "SELECT * FROM `Utilisateur` WHERE `email` = %s;", + "selectEmpruntByUser" : "SELECT * FROM `Emprunt` WHERE `Utilisateur` = %s;", } def __init__(self, host:str ="localhost", user:str="root", passwd:str="1234", port:int=3306, debug:bool=False) -> None: @@ -105,7 +106,9 @@ def mkRequest(self, request:str, verbose=False, *args) -> None: *args : tuple : the arguments to pass to the request """ try : - # Convertir les arguments en chaînes de caractères, ajouter des guillemets autour des chaînes de caractères, et gérer les valeurs NULL + if request not in self._requetes.keys(): + print(f"\033[31mErreur : La requête {request} n'existe pas dans la base de donnée !\033[0m") + return args = list(args) for i in range(len(args)): if args[i] == "": @@ -114,11 +117,40 @@ def mkRequest(self, request:str, verbose=False, *args) -> None: print(f"#{self._requetes[request] % tuple(args)}") self.cursor.execute(self._requetes[request], tuple(args)) except Exception as e: - print(f" La requête à échouée : {self._requetes[request] % tuple(args)}\n---, Erreur : {e}, ligne : {e.__traceback__.tb_lineno}") - print("Args : ", args) - print(f"Nombre de placeholders : {self._requetes[request].count('%s')}") - print(f"Nombre d'arguments : {len(args)}\n-------------------------------------------------- ") - + if self.retryDatabaseConnection() == False: + print(f" \033[31mLa requête à échouée : {self._requetes[request] % tuple(args)}\n---, Erreur : {e}, ligne : {e.__traceback__.tb_lineno}, {pymysql.MySQLError}---\033[0m") + print("Args : ", args) + print(f"Nombre de placeholders : {self._requetes[request].count('%s')}") + print(f"Nombre d'arguments : {len(args)}\n--------------------------------------------------\033[0m") + print(f"Cursor : {type(self.cursor)} Actif : {self.cursor!=None}") + print(f"Database : {type(self.db)} Actif : {self.db!=None}") + else : + self.mkRequest(request, verbose, *args) + + + def retryDatabaseConnection(self) -> bool: + """This function retries to connect to the database.""" + print("Connexion à la base de donnée perdu, tentative de reconnexion...") + try : + maxRetries = 3 + retryDelay = 1 #secondes + for i in range(maxRetries): + try: + self.cursor.close() + self.db.close() + self.db = pymysql.connect(host=self.host, charset="utf8mb4",user=self.user, passwd=self.passwd, port=self.port, db="BookWorm", init_command='SET sql_mode="NO_ZERO_IN_DATE,NO_ZERO_DATE"') + self.cursor = self.db.cursor() + print("Reconnexion à la base de donnée réussie !") + return True + except : + time.sleep(retryDelay) + pass + print("Erreur : Impossible de se reconnecter à la base de donnée !") + return False + except Exception as e: + print("Erreur : Impossible de se reconnecter à la base de donnée ! Une erreur est survenue : ",e) + exit(1) + def __str__(self) -> str: return f"Database host : {self.host}, user : {self.user}, password : {self.passwd}, port : {self.port}, debug : {self.debug}" diff --git a/searchEngine.py b/searchEngine.py index 33f8df0..cdb616d 100644 --- a/searchEngine.py +++ b/searchEngine.py @@ -52,7 +52,7 @@ def getPointDeVenteNameByAddresse(db:database.db, addresse: str)->str: db.mkRequest("selectPointDeVenteByAdresse", False, addresse) result = db.cursor.fetchall() if result == None or result == []: return "Nom du point de vente inconnu" - return f"{result[0][0]}" + return f"{result[0][1]}" except Exception as e: print(f"Une erreur est survenue lors de la recherche du point de vente :{e}, ligne : {e.__traceback__.tb_lineno}") @@ -114,6 +114,8 @@ def searchPointDeVente(recherche:str, db:database.db, onlyOne:bool = False)->lis recherche = recherche.strip().split() request = ["selectPointDeVenteByNom", "selectPointDeVenteByAdresse"] result = searchEngine(recherche, request, db) + + print(result) temp = [] for i in result:#enlève les doublons if i not in temp and i != None and i != ( ): diff --git a/server.py b/server.py index 582f4b1..0a495de 100644 --- a/server.py +++ b/server.py @@ -26,7 +26,6 @@ def searchLivre(self, search:str, sort:str, auteur:str="Tous") -> str: sort = "sortByAlpha" try : searchResult = searchEngine.searchLivre(search,self.db) - #print("SEARCH RESULT", searchResult) if searchResult == None : return None searchResult= operationOnDataBase.sortLivre(searchResult,sort) if auteur != "Tous": @@ -95,7 +94,6 @@ def checkLogin(self, email:str, password:str) -> str: try : self.db.mkRequest("selectUserByEmail", False, email) user = self.db.cursor.fetchall() - print("USER",user) if user is not None and user != () and user != []: if user[0][1] == password: return self.makeResponse(content="success") @@ -125,6 +123,28 @@ def getUserInfo(self, email:str, password:str) -> str: print("\033[31mErreur lors de la tentative de conneion : ",e, e.__traceback__.tb_lineno, user, "\033[0m") return self.makeResponse(is_error=True, error_message="Oups, une erreur est survenue, veuillez réessayer ultérieurement") + @cherrypy.expose + @cherrypy.tools.json_out() + def getEmprunt(self, email:str, password:str)->str: + try : + #check password before + self.db.mkRequest("selectUserByEmail", True, email) + user = self.db.cursor.fetchall() + if user is not None and user != () and user != []: + if user[0][1] == password: + self.db.mkRequest("selectEmpruntByUser", True, email) + emprunts = self.db.cursor.fetchall() + if emprunts is not None and emprunts != () and emprunts != []: + emprunts = utils.formatEmpruntsToJson(emprunts) + return self.makeResponse(content=emprunts) + else: + return self.makeResponse(is_error=True, error_message="Aucun emprunt trouvé") + else: + return self.makeResponse(is_error=True, error_message="Mot de passe incorrect") + except Exception as e: + print("\033[31mErreur lors de la récupération des réservations : ",e, e.__traceback__.tb_lineno, emprunts, "\033[0m") + return self.makeResponse(is_error=True, error_message="Oups, une erreur est survenue, veuillez réessayer ultérieurement") + @cherrypy.expose def index(self) -> str : return open('www/html/index.html', encoding="utf-8") diff --git a/test.py b/test.py index 93556de..677fa52 100644 --- a/test.py +++ b/test.py @@ -1,122 +1,74 @@ -[ - { - "ISBN": "2070624544", - "titre": "Harry Potter - : Harry Potter et le prisonnier d'Azkaban", - "auteur": "J. K. Rowling", - "description": "Harry Potter a treize ans. Apr\u00e8s des vacances insupportables chez les horribles Dursley, il retrouve ses fid\u00e8les amis, Ron et Hermione, pour prendre le train qui les ram\u00e8ne au coll\u00e8ge Poudlard. Le monde des gens ordinaires, les Moldus, comme celui des sorciers, est en \u00e9moi : aux derni\u00e8res nouvelles, Sirius Black, un dangereux criminel proche de Voldemort, s'est \u00e9chapp\u00e9 de la prison d'Azkaban. Les redoutables gardiens de la prison assureront la s\u00e9curit\u00e9 du coll\u00e8ge Poudlard, car le prisonnier \u00e9vad\u00e9 recherche Harry Potter, responsable de l'\u00e9limination de son ma\u00eetre. C'est donc sous bonne garde que l'apprenti sorcier fait sa troisi\u00e8me rentr\u00e9e. Au programme : des cours de divination, la fabrication d'une potion de ratatinage, le dressage des hippogriffes... Mais Harry est-il vraiment \u00e0 l'abri du danger qui le menace ?", - "note": 10.0, - "dateDeParution": "19/10/1999", - "status": "emprunt\u00e9", - "genre": "Fantastique", - "format": "Grand Format", - "prix": 9.99, - "pointDeVente": "17, avenue Victor-Hugo Centre commercial Victor-Hugo - 26000 Valence\n\n", - "pointDeVenteName": "Fnac", - "editeur": "Gallimard" - }, - { - "ISBN": "2070541290", - "titre": "Harry Potter - Tome 2 : Harry potter et la chambre des secrets", - "auteur": "J. K. Rowling", - "description": "Cette deuxi\u00e8me aventure d'Harry Potter m\u00eale avec g\u00e9nie humour, myst\u00e8re et frisson. L'intrigue savamment ficel\u00e9e et pleine de rebondissements inattendus envo\u00fbte litt\u00e9ralement le lecteur de la premi\u00e8re \u00e0 la derni\u00e8re page. Un r\u00e9gal !", - "note": 10.0, - "dateDeParution": "01/11/1999", - "status": "hors stock", - "genre": "Fantastique", - "format": "Grand Format", - "prix": 22.5, - "pointDeVente": "12, place des clercs 26000 Valence", - "pointDeVenteName": "La Licorne", - "editeur": "Gallimard" - }, - { - "ISBN": "2070543587", - "titre": "Harry Potter - Tome 4 : Harry potter et la coupe de feu", - "auteur": "J. K. Rowling", - "description": "Apr\u00e8s un horrible \u00e9t\u00e9 chez les Dursley, Harry Potter entre en quatri\u00e8me ann\u00e9e au coll\u00e8ge de Poudlard. \u00c0 quatorze ans, il voudrait simplement \u00eatre un jeune sorcier comme les autres, retrouver ses amis Ron et Hermione, assister avec eux \u00e0 la Coupe du Monde de Quidditch, apprendre de nouveaux sortil\u00e8ges et essayer des potions inconnues. Une grande nouvelle l'attend \u00e0 son arriv\u00e9e : la tenue \u00e0 Poudlard d'un tournoi de magie entre les plus c\u00e9l\u00e8bres \u00e9coles de sorcellerie. D\u00e9j\u00e0 les spectaculaires d\u00e9l\u00e9gations \u00e9trang\u00e8res font leur entr\u00e9e... Harry se r\u00e9jouit. Trop vite. Il va se trouver plong\u00e9 au coeur des \u00e9v\u00e9nements les plus dramatiques qu'il ait jamais eu \u00e0 affronter.\nEnvo\u00fbtant, dr\u00f4le, bouleversant, ce quatri\u00e8me tome est le pilier central des aventures de Harry Potter.", - "note": 10.0, - "dateDeParution": "01/11/2000", - "status": "disponible", - "genre": "Fantastique", - "format": "Grand Format", - "prix": 14.5, - "pointDeVente": "Place Charles de Gaulle \u00e0 Chabeuil (Dr\u00f4me)", - "pointDeVenteName": " Librairie Ecriture", - "editeur": "Gallimard" - }, - { - "ISBN": "2070556859", - "titre": "Harry Potter - Tome 5 : Harry potter et l'ordre du phenix ", - "auteur": "J. K. Rowling", - "description": "\u00c0 quinze ans, Harry entre en cinqui\u00e8me ann\u00e9e \u00e0 Poudlard, mais il n'a jamais \u00e9t\u00e9 si anxieux. L'adolescence, la perspective des examens et ces \u00e9tranges cauchemars... Car Celui-Dont-On-Ne-Doit-Pas-Prononcer-Le-Nom est de retour. Le minist\u00e8re de la Magie semble ne pas prendre cette menace au s\u00e9rieux, contrairement \u00e0 Dumbledore. La r\u00e9sistance s'organise alors autour de Harry qui va devoir compter sur le courage et la fid\u00e9lit\u00e9 de ses amis de toujours... ", - "note": 10.0, - "dateDeParution": "01/12/2003", - "status": "disponible", - "genre": "Fantastique", - "format": "Grand Format", - "prix": 12.99, - "pointDeVente": "Place Charles de Gaulle \u00e0 Chabeuil (Dr\u00f4me)", - "pointDeVenteName": " Librairie Ecriture", - "editeur": "Gallimard" - }, - { - "ISBN": "2070572676", - "titre": "Harry Potter - Tome 6 : Harry potter et le prince de sang-mele ", - "auteur": "J. K. Rowling", - "description": "Harry, Ron et Hermione entrent en sixi\u00e8me ann\u00e9e \u00e0 Poudlard o\u00f9 ils vont vivre leur derni\u00e8re ann\u00e9e avant la majorit\u00e9 qui est fix\u00e9e, chez les sorciers, \u00e0 l'\u00e2ge de dix-sept ans. Des \u00e9v\u00e9nements particuli\u00e8rement marquants vont contribuer \u00e0 faire passer Harry du statut d'adolescent \u00e0 celui d'homme. Ce tome, sur fond de guerre contre un Voldemort plus puissant que jamais, se r\u00e9v\u00e8le plus sombre que les pr\u00e9c\u00e9dents. Secrets, alliances et trahisons conduisent aux \u00e9v\u00e9nements les plus dramatiques qu'Harry ait eu \u00e0 affronter. Mais, en... ", - "note": 10.0, - "dateDeParution": "01/10/2005", - "status": "disponible", - "genre": "Fantastique", - "format": "Grand Format", - "prix": 10.99, - "pointDeVente": "31 rue Madier de Montjau\n26000 Valence", - "pointDeVenteName": "L'\u00c9tincelle", - "editeur": "Gallimard" - }, - { - "ISBN": "2070615367", - "titre": "Harry Potter - Tome 7 : Harry potter et les reliques de la mort", - "auteur": "J. K. Rowling", - "description": "\u00abEnvers et contre tout\u00bb est une caract\u00e9ristique-cl\u00e9 chez J.K. Rowling. Paradoxalement, c'est lorsqu'elle a continu\u00e9 \u00e0 \u00e9crire avec une \u00e9nergie, une passion, un engagement inentam\u00e9s, en particulier \u00e0 partir du tome 4 - alors qu'elle \u00e9tait devenue l'une des femmes les plus c\u00e9l\u00e8bres et riches au monde, et que chaque suite \u00e9tait attendue par des dizaines de millions de lecteurs du monde entier - , qu'elle force le plus l'admiration. Elle accomplit la mission qu'elle s'est donn\u00e9e sans faillir, sans jamais d\u00e9cevoir.\nL'ambition de... ", - "note": 10.0, - "dateDeParution": "27/10/2007", - "status": "emprunt\u00e9", - "genre": "Fantastique", - "format": "Grand Format", - "prix": 15.99, - "pointDeVente": "17, avenue Victor-Hugo Centre commercial Victor-Hugo - 26000 Valence\n\n", - "pointDeVenteName": "Fnac", - "editeur": "Gallimard" - }, - { - "ISBN": "2070615367", - "titre": "Harry Potter - Tome 7 : Harry potter et les reliques de la mort", - "auteur": "J. K. Rowling", - "description": "\u00abEnvers et contre tout\u00bb est une caract\u00e9ristique-cl\u00e9 chez J.K. Rowling. Paradoxalement, c'est lorsqu'elle a continu\u00e9 \u00e0 \u00e9crire avec une \u00e9nergie, une passion, un engagement inentam\u00e9s, en particulier \u00e0 partir du tome 4 - alors qu'elle \u00e9tait devenue l'une des femmes les plus c\u00e9l\u00e8bres et riches au monde, et que chaque suite \u00e9tait attendue par des dizaines de millions de lecteurs du monde entier - , qu'elle force le plus l'admiration. Elle accomplit la mission qu'elle s'est donn\u00e9e sans faillir, sans jamais d\u00e9cevoir.\nL'ambition de... ", - "note": 10.0, - "dateDeParution": "27/10/2007", - "status": "emprunt\u00e9", - "genre": "Fantastique", - "format": "Grand Format", - "prix": 15.99, - "pointDeVente": "17, avenue Victor-Hugo Centre commercial Victor-Hugo - 26000 Valence\n\n", - "pointDeVenteName": "Fnac", - "editeur": "Gallimard" - }, - { - "ISBN": "9782070518425", - "titre": "Harry Potter, tome 1 : Harry Potter \u00e0 l'\u00e9cole des sorciers\n", - "auteur": "J. K. Rowling", - "description": "Pour et Mrs Dursley, qui habitaient au 4, Privet Drive, avaient toujours affirm\u00e9 avec la plus grande fiert\u00e9 qu'ils \u00e9taient parfaitement nor\u00admaux, merci pour eux. Jamais quiconque n'aurait imagin\u00e9 qu'ils puissent se trouver impliqu\u00e9s dans quoi que ce soit d'\u00e9trange ou de myst\u00e9rieux. Ils n'avaient pas de temps \u00e0 perdre avec des sornettes.", - "note": 10.0, - "dateDeParution": "01/01/1998", - "status": "emprunt\u00e9", - "genre": "Fantastique", - "format": "Poche", - "prix": 10.99, - "pointDeVente": "12, place des clercs 26000 Valence", - "pointDeVenteName": "La Licorne", - "editeur": "Gallimard" - } -] \ No newline at end of file + + La requête à échouée : SELECT * FROM `Livre` WHERE `ISBN` LIKE 2070624544; +---, Erreur : Packet sequence number wrong - got 1 expected 17, ligne : 121 +Args : ['2070624544'] +Nombre de placeholders : 1 +Nombre d'arguments : 1 +-------------------------------------------------- + La requête à échouée : SELECT * FROM `Livre` WHERE `ISBN` LIKE 2070615367; +---, Erreur : Packet sequence number wrong - got 101 expected 17, ligne : 121 + La requête à échouée : SELECT * FROM `Livre` WHERE `ISBN` LIKE 2070572676; +---, Erreur : (2013, 'Lost connection to MySQL server during query'), ligne : 121 +Args : ['2070572676'] +Nombre de placeholders : 1 + La requête à échouée : SELECT * FROM `Auteur` WHERE `ID` = 31; +---, Erreur : Packet sequence number wrong - got 111 expected 17, ligne : 121Args : ['2070615367'] +DATA () +192.168.1.28 - - [18/May/2024:15:29:15] "GET /getLivre?isbn=2070624544 HTTP/1.1" 200 33 "http://192.168.1.20:8080/account" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36" + +Args : [31] +Nombre de placeholders : 1 +Nombre d'arguments : 1 +-------------------------------------------------- +Une erreur est survenue lors de la recherche de l'auteur :tuple index out of range, ligne : 38 +######### selectPointDeVenteByAdresse ('17, avenue Victor-Hugo Centre commercial Victor-Hugo - 26000 Valence\n\n',) SELECT Nom FROM `Point de vente` WHERE `Adresse` LIKE 17, avenue Victor-Hugo Centre commercial Victor-Hugo - 26000 Valence + +;######### selectAuteurByID (2,) SELECT * FROM `Auteur` WHERE `ID` = 2; +######### + La requête à échouée : SELECT * FROM `Auteur` WHERE `ID` = 2; +---, Erreur : (0, ''), ligne : 121Nombre de placeholders : 1 +Nombre d'arguments : 1 +-------------------------------------------------- +DATA [] +Nombre d'arguments : 1 +-------------------------------------------------- +DATA [] + +Args : [2] +Nombre de placeholders : 1 +Nombre d'arguments : 1 +-------------------------------------------------- +######### selectPointDeVenteByAdresse ('31 rue Madier de Montjau\n26000 Valence',) SELECT Nom FROM `Point de vente` WHERE `Adresse` LIKE 31 rue Madier de Montjau +26000 Valence; +######### + La requête à échouée : SELECT Nom FROM `Point de vente` WHERE `Adresse` LIKE 17, avenue Victor-Hugo Centre commercial Victor-Hugo - 26000 Valence + +; +---, Erreur : (0, ''), ligne : 121 +Args : ['17, avenue Victor-Hugo Centre commercial Victor-Hugo - 26000 Valence\n\n'] +Nombre de placeholders : 1 +Nombre d'arguments : 1 +-------------------------------------------------- + +######### selectLivreByISBN ('1041834365',) SELECT * FROM `Livre` WHERE `ISBN` LIKE 1041834365; +######### + La requête à échouée : SELECT Nom FROM `Point de vente` WHERE `Adresse` LIKE 31 rue Madier de Montjau +26000 Valence; +---, Erreur : (0, ''), ligne : 121 +Args : ['31 rue Madier de Montjau\n26000 Valence'] +Nombre de placeholders : 1 +Nombre d'arguments : 1 +-------------------------------------------------- +######### + La requête à échouée : SELECT * FROM `Livre` WHERE `ISBN` LIKE 1041834365; +---, Erreur : (0, ''), ligne : 121 +Args : ['1041834365'] +Nombre de placeholders : 1 +Nombre d'arguments : 1 +-------------------------------------------------- +DATA [] +192.168.1.28 - - [18/May/2024:15:29:15] "GET /getLivre?isbn=2070615367 HTTP/1.1" 200 33 "http://192.168.1.20:8080/account" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36" +192.168.1.28 - - [18/May/2024:15:29:15] "GET /getLivre?isbn=2070572676 HTTP/1.1" 200 33 "http://192.168.1.20:8080/account" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36" +192.168.1.28 - - [18/May/2024:15:29:15] "GET /getLivre?isbn=2017010090 HTTP/1.1" 200 1283 "http://192.168.1.20:8080/account" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36" +192.168.1.28 - - [18/May/2024:15:29:15] "GET /getLivre?isbn=2070615367 HTTP/1.1" 200 1272 "http://192.168.1.20:8080/account" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36" +192.168.1.28 - - [18/May/2024:15:29:15] "GET /getLivre?isbn=1041834365 HTTP/1.1" 200 33 "http://192.168.1.20:8080/account" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36" diff --git a/utils.py b/utils.py index 39a8a43..b1e3cf3 100644 --- a/utils.py +++ b/utils.py @@ -80,9 +80,7 @@ def formatAuteurToJson(data:list[tuple])->json: def formatPointDeVenteToJson(data:list[tuple])->json: try : result = {} - print("DATA",data) for item in data: - print("TEST",item) if len(item) != 4: item = item[:4] adresse, nom, url, tel = item @@ -94,7 +92,7 @@ def formatPointDeVenteToJson(data:list[tuple])->json: json_result = json.dumps(result, indent=4) return json_result except Exception as e: - print("\033[31mErreur lors de la conversion en JSON : ",e, e.__traceback__.tb_lineno, "\033[0m") + print("\033[31mErreur lors de la conversion en JSON du Point de Vente : ",e, e.__traceback__.tb_lineno, data, "\033[0m") return None def formatEditeurToJson(data:list[tuple])->json: @@ -164,6 +162,27 @@ def formatUserToJson(data:list[tuple])->json: } json_result = json.dumps(result, indent=4) return json_result + except Exception as e: + print("\033[31mErreur lors de la conversion en JSON : ",e, e.__traceback__.tb_lineno, "\033[0m") + return None + + +def formatEmpruntsToJson(data:list[tuple])->json: + try : + result = {} + print("DATA",data) + for item in data: + if len(item) != 4: + item = item[:4] + ID, livre, date, utilsateur = item + result[ID] = { + 'isbn':livre, + 'Date':date.strftime("%d/%m/%Y"), + 'Utilsateur':utilsateur + } + print("JSON",result) + json_result = json.dumps(result, indent=4) + return json_result except Exception as e: print("\033[31mErreur lors de la conversion en JSON : ",e, e.__traceback__.tb_lineno, "\033[0m") return None \ No newline at end of file diff --git a/www/html/account.html b/www/html/account.html index 2452782..a00a11d 100644 --- a/www/html/account.html +++ b/www/html/account.html @@ -7,13 +7,23 @@ -
+
-

-

Mes réservations :

-
-
-
+

Mes informations :

+
    +

    Mes réservations :

    +
      +
      +
      + harry book +
      +
      + search new book +
      + + + + \ No newline at end of file diff --git a/www/html/index.html b/www/html/index.html index 2c0e86a..1909a90 100644 --- a/www/html/index.html +++ b/www/html/index.html @@ -7,7 +7,6 @@ -
      @@ -24,13 +23,11 @@

      BookWorm

      friendly book -
      - - - -
      + + +
      livre
      diff --git a/www/img/account.svg b/www/img/account.svg new file mode 100644 index 0000000..d992990 --- /dev/null +++ b/www/img/account.svg @@ -0,0 +1 @@ +MON COMPTE \ No newline at end of file diff --git a/www/img/harryBook.svg b/www/img/harryBook.svg new file mode 100644 index 0000000..a6d2171 --- /dev/null +++ b/www/img/harryBook.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/www/img/livres/2072847923.jpg b/www/img/livres/2072847923.jpg index 1d6306a..a11f09c 100644 Binary files a/www/img/livres/2072847923.jpg and b/www/img/livres/2072847923.jpg differ diff --git a/www/img/searchNewBook.svg b/www/img/searchNewBook.svg new file mode 100644 index 0000000..df6c2ff --- /dev/null +++ b/www/img/searchNewBook.svg @@ -0,0 +1 @@ +EMPRUNTER DES LIVRES \ No newline at end of file diff --git a/www/js/account.js b/www/js/account.js index 6c4ed5e..4a41af0 100644 --- a/www/js/account.js +++ b/www/js/account.js @@ -1,26 +1,71 @@ -const API_URL = 'http://192.168.1.20:8080' +const API_URL = 'http://192.168.1.20:8080'; -let decodedCookie = decodeURIComponent(document.cookie).split(';');//decodeURIComponent permet de decoder les caractères spéciaux -for (let i = 0; i < decodedCookie.length; i++) {//on parcourt le tableau de cookies - let c = decodedCookie[i]; - while (c.charAt(0) === ' ') { - c = c.substring(1); - } - if (c.indexOf('email=') === 0) { - const email = c.substring("email=".length, c.length); - const password = c.substring("password=".length, c.length); - } +let userInfo = ""; +let email, password; + +async function checkLoginAndGetUserInfo() { + let decodedCookie = decodeURIComponent(document.cookie).split(';'); + for (let i = 0; i < decodedCookie.length; i++) { + let c = decodedCookie[i].trim(); + if (c.startsWith('email=')) { + email = c.substring('email='.length); + } + if (c.startsWith('password=')) { + password = c.substring('password='.length); + } + } + const response = await fetch(`${API_URL}/checkLogin?email=${encodeURIComponent(email)}&password=${encodeURIComponent(password)}`); + const data = await response.json(); + if (data["content"] === 'success') { + let reponse = await fetch(`${API_URL}/getUserInfo?email=${encodeURIComponent(email)}&password=${encodeURIComponent(password)}`); + reponse = await reponse.json(); + userInfo = JSON.parse(reponse["content"]); + } else { + window.location.href = '/login'; + } +} + +let emprunts = ""; +async function GetEmprunts() { + const reponse = await fetch(`${API_URL}/getEmprunt?email=${encodeURIComponent(email)}&password=${encodeURIComponent(password)}`); + const data = await reponse.json(); + emprunts = JSON.parse(data["content"]); +} + +async function GetLivreTitre(isbn) { + const response = await fetch(`${API_URL}/getLivre?isbn=${encodeURIComponent(isbn)}`); + const data = await response.json(); + const livreData = JSON.parse(data["content"]); + return livreData[isbn]["titre"]; } -let reponse = await fetch(`${API_URL}/checkLogin?email=${email}&password=${password}`); -const data = await response.json(); -if (data["content"] === 'success') { - document.getElementById('account').style.display = 'block'; - let reponse = await fetch(`${API_URL}/getUserInfo?email=${email}&password=${password}`); - let userInfo = await reponse.json(); - console.log(userInfo); - document.getElementById('welcome').innerHTML = `

      Bienvenue ${email}

      `; -} else { - document.getElementById('account').style.display = 'none'; - document.getElementById('Error').innerHTML = '

      Oups, cette page est réservée aux membres connectés

      Connectez-vous'; -} \ No newline at end of file +checkLoginAndGetUserInfo().then(() => { + console.log("USERINFO", userInfo); + const userName = userInfo[email]["nom"]; + const formattedUserName = userName.charAt(0).toUpperCase() + userName.slice(1); + document.getElementById('welcome').innerHTML = `

      Bienvenue sur BookWorm ${formattedUserName} !

      `; + GetEmprunts().then(async () => { + console.log("EMPRUNTS", emprunts); + const divEmprunt = document.getElementById('emprunts'); + for (const id of Object.keys(emprunts)) { + const titre = await GetLivreTitre(emprunts[id]["isbn"]); + const dateStr = emprunts[id]["Date"]; // votre chaîne de caractères au format YYYY-MM-DD + const [day, month, year] = dateStr.split("/"); + const today = new Date(); + const date = new Date(`${year}-${month}-${day}`); + const diffInMilliseconds = Math.abs(today - date); + const diffInDays = Math.ceil(diffInMilliseconds / (1000 * 3600 * 24)); + if (30-diffInDays < 0) { + divEmprunt.innerHTML += `
    • ${titre} est en retard de ${diffInDays} jour(s)
    • `; + } else { + divEmprunt.innerHTML += `
    • ${titre} retour attendu dans ${30-diffInDays} jour(s)
    • `; + } + } + let divInfo = document.getElementById('infos') + divInfo.innerHTML = `
    • Nom : ${userInfo[email]["nom"]}
    • \ +
    • Prénom : ${userInfo[email]["prénom"]}
    • \ +
    • Adresse : ${userInfo[email]["adresse"]}
    • \ +
    • Tel : ${userInfo[email]["tel"]}
    • \ + ` + }); +}); \ No newline at end of file diff --git a/www/js/index.js b/www/js/index.js index ee71d44..d97c9ae 100644 --- a/www/js/index.js +++ b/www/js/index.js @@ -2,6 +2,27 @@ const API_URL = 'http://192.168.1.20:8080' const searchInput = document.querySelector('input.form-control'); const searchButton = document.querySelector('button#searchButton'); + +let email, password; + +async function checkLoginAndGetUserInfo() { + let decodedCookie = decodeURIComponent(document.cookie).split(';'); + for (let i = 0; i < decodedCookie.length; i++) { + let c = decodedCookie[i].trim(); + if (c.startsWith('email=')) { + email = c.substring('email='.length); + } + if (c.startsWith('password=')) { + password = c.substring('password='.length); + } + } + const response = await fetch(`${API_URL}/checkLogin?email=${encodeURIComponent(email)}&password=${encodeURIComponent(password)}`); + const data = await response.json(); + if (data["content"] === 'success') { + document.getElementById("account").src = "../img/account.svg" + } +} +checkLoginAndGetUserInfo() async function updateBestLivres() { await fetch(`${API_URL}/updateBestLivres`); } diff --git a/www/js/livre.js b/www/js/livre.js index 12abf5d..34f9ffa 100644 --- a/www/js/livre.js +++ b/www/js/livre.js @@ -25,7 +25,7 @@ async function loadLivre(isbn) { let response = await fetch(`${API_URL}/getLivre?isbn=${isbn}`); let livreData = await response.json(); livreData = JSON.parse(livreData["content"]); - console.log("response: ", livreData); + console.log("livre: ", livreData); return livreData[isbn]; } const urlParams = new URLSearchParams(window.location.search); diff --git a/www/js/login.js b/www/js/login.js index 4bbe5c9..b6dcdc6 100644 --- a/www/js/login.js +++ b/www/js/login.js @@ -1,5 +1,30 @@ const API_URL = 'http://192.168.1.20:8080' +async function checkLoginAndGetUserInfo() { + let decodedCookie = decodeURIComponent(document.cookie).split(';'); + let email, password; + for (let i = 0; i < decodedCookie.length; i++) { + let c = decodedCookie[i]; + while (c.charAt(0) === ' ') { + c = c.substring(1); + } + if (c.indexOf('email=') === 0) { + email = c.substring("email=".length, c.length); + } + if (c.indexOf('password=') === 0) { + password = c.substring("password=".length, c.length); + } + } + if (email && password) { + let response = await fetch(`${API_URL}/checkLogin?email=${email}&password=${password}`); + const data = await response.json(); + if (data["content"] === 'success') { + window.location.href = '/account'; + } + } +} + +checkLoginAndGetUserInfo(); const signupButton = document.getElementById('signupButton'); const signinButton = document.getElementById('signinButton');