From 38e8394053fb07612ac177f5b508dfc10e6cf15a Mon Sep 17 00:00:00 2001 From: nocerae Date: Wed, 7 Apr 2021 04:09:14 +0100 Subject: [PATCH] first project update --- .idea/vcs.xml | 6 ++ APIManager.py | 45 ++++++----- Database.py | 202 +++++++++++++++++++++-------------------------- EmailManager.py | 43 +++++----- UserInterface.py | 194 +++++++++++++++++++++------------------------ main.py | 51 ++++++------ 6 files changed, 259 insertions(+), 282 deletions(-) create mode 100644 .idea/vcs.xml diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/APIManager.py b/APIManager.py index d917606..969fd0e 100644 --- a/APIManager.py +++ b/APIManager.py @@ -1,41 +1,40 @@ -import requests # to get/download the data from the api -import json # parse the api data +# Reference: Python Requests Tutorial: Request Web Pages, Download Images, POST Data, Read JSON, and More +# https://www.youtube.com/watch?v=tb8gHvYlCFs&t=839s -""" -Class APIManager +import requests # to get/download the data from the news Api +import json # to decode the api response -Gestisce la comunicazione HTTP con le API che forniscono i dati per le newsletter +""" +Class APIManager +Handles HTTP communication with the API that provide data for the news service """ class APIManager: """ +Method: getNews - Metodo: getNews - - Invia una richiesta GET tramite la libreria requests alle API trovate online - - - Costruisce il dizionario con i parametri della richiesta (header + querystring) - - Invia la richiesta con metodo GET all'url delle API (trovato online su rapidapi.com) - - decodifica la risposta json in un Dizionario e restituisce i campi d'interesse (titolo, corpo, url) della news +Sends a GET request via the requests library to the API + - Builds the dictionary with the request parameters (header + querystring) + - Sends the request with GET method to the API url (rapidapi.com) + - Decodes the json response in a dictionary and returns the fields of interest (title, body, url) of the news """ - def getNews(self, category): url = "https://contextualwebsearch-websearch-v1.p.rapidapi.com/api/search/NewsSearchAPI" # url of the api - # I parametri che andiamo a fornire alle API per la nostra richiesta. - # Questi sono da trovare nella documentazione delle API + # The parameters of the API request + # Reference: rapidapi.com querystring = { - "q": f"{category}", # query to follow, topic to get the about - "pageNumber": "1", # no of pages cna be change + "q": f"{category}", # news request based on category + "pageNumber": "1", # n. of pages can be changed "pageSize": "1", # size of the page should limit to paragraphs "autoCorrect": "true", # spelling checker - "fromPublishedDate": "null", # date init - "toPublishedDate": "null" # date end + "fromPublishedDate": "null", # initial date + "toPublishedDate": "null" # end date } headers = { @@ -43,13 +42,13 @@ class APIManager: 'x-rapidapi-host': "contextualwebsearch-websearch-v1.p.rapidapi.com" # hosting sender } - # creating requests + # creating request response = requests.request("GET", url, headers=headers, params=querystring) - responseText = response.text # leggiamo la risposta in JSON che ci ha dato il server (si trova nel campo text) - data = json.loads(responseText) # fornattiamo il JSON in un dizionario Python + responseText = response.text # reads the JSON response provided by API (found in the text field) + data = json.loads(responseText) # converts JSON response in a Python dictionary - # Estrai i dati dal dizionario data e ritorna i singoli campi + # Extracts data from the "data" dictionary and returns them title = data['value'][0]['title'] body = data['value'][0]['body'] url = data['value'][0]['url'] diff --git a/Database.py b/Database.py index 95ff8f7..9e8741c 100644 --- a/Database.py +++ b/Database.py @@ -1,47 +1,46 @@ -import pandas as pd -import os +import pandas as pd # to manipulate data in .csv format +import os # to create directories and check their existence class DatabaseManager: """ - Metodo: checkDatabaseExists +Method: checkDatabaseExists. - Controlla se nella cartella dello script esistono i file csv che contengono i dati del software relativi agli utenti e le iscrizioni. - Se questi non esistono: - - Crea una cartella ./data - - Crea due Dataframe da Pandas che conterranno i dati relativi a utenti e iscrizioni. - - Salva i dataframe in due file .csv distinti all'interno della cartella ./data + Checks if the .csv files that contain user and subscription data exist in the script folder. + If they do not exist: + - Creates a ./data folder + - Creates two Pandas Dataframes that will contain user and subscription data. + - Saves the Dataframes in two separate .csv files inside the ./data folder """ def checkDatabaseExists(self): - # check if data folder exists in root folder, either creates it + # creates data folder if it doesn't exist if not os.path.exists("./data"): print("Creating data folder...") os.mkdir("data") # database files - files = ["users.csv", 'subscriptions.csv'] #Dichiara una lista di stringhe con i nomi dei fila che vuole utilizzare + files = ["users.csv", 'subscriptions.csv'] # Declare a list of strings with the names of the files it wants to use for file in files: - # check if files exists, else create them + # checks if files exist, otherwise it creates them if not os.path.exists(f"./data/{file}"): print(f"{file} Not Exists") print(f"Creating {file}...") if 'users' in file: - #Crea il database con pandas e lo salva nel file users.csv - # init the dataframe + # Creates the Pandas Dataframe and saves it in the users.csv file df = pd.DataFrame({ "name": [], "username": [], "password": [], }) - # save the dataframe to users + # saves the dataframe into users.csv df.to_csv("./data/users.csv", index=False) elif 'subscriptions' in file: - # init the dataframe + # Creates the Pandas Dataframe and saves it in the subscriptions.csv file df = pd.DataFrame({ "username": [], "email": [], @@ -58,17 +57,17 @@ class DatabaseManager: "culture": [], "religion": [], }) - # save the dataframe + # saves the dataframe into subscriptions.csv df.to_csv("./data/subscriptions.csv", index=False) ''' - Metodo: getUsersDF +Method: getUsersDF - - Chiama il metodo checkDatabaseExists - - Legge e restituisce il dataframe con i dati relativi agli utenti - +- Calls the checkDatabaseExists method +- Reads and returns the dataframe containing the user data ''' + def getUsersDF(self): self.checkDatabaseExists() df = pd.read_csv("./data/users.csv") @@ -77,11 +76,10 @@ class DatabaseManager: ''' - Metodo: getSubscriptionsDF - - - Chiama il metodo checkDatabaseExists - - Legge e restituisce il dataframe con i dati relativi alle iscrizioni +Method: getSubscriptionsDF +- Calls the checkDatabaseExists method +- Reads and returns the dataframe containing the subscriptions data ''' def getSubscriptionsDF(self): self.checkDatabaseExists() @@ -90,107 +88,94 @@ class DatabaseManager: ''' - Metodo: pintSubscriptions - - Stampa la tabella delle iscrizioni - - - Chiama il metodo getSubscriptionsDF - - Stampa il risultato +Method: printSubscriptions +- Calls the getSubscriptionsDF method +- Prints the subscriptions table ''' def printSubscriptions(self): print(self.getSubscriptionsDF()) ''' - Metodo: removeUser - Param: username - - - Controlla se username è contenuto nella tabella users.csv - - Elimina il record relativo a username in entrambe le tabelle - - Salva le modifiche effettuate +Method: deleteUser +Param: username +- Checks if username is contained in the users.csv table +- Delete the username records from files +- Saves the changes made ''' - - def removeUser(self, uname): + def deleteUser(self, uname): dfSub = self.getSubscriptionsDF() dfUsers = self.getUsersDF() - # if user found - if dfSub['username'].str.contains(uname).any(): # if username exists in any record - print("Username found in database") - # drop the row from users.csv and subscriptions.csv + if dfSub['username'].str.contains(uname).any(): # if username exists in any record + # print("Username found in database") - # Rimuove la riga dalla tabella dfSub che contiene 'uname' nel campo username. Con inplace = True modifico la tabella senza creare una copia + # Deletes the row from the dfSub table that contains 'uname' in the username field. + # With inplace = True the table is modified without creating a copy dfSub.drop(dfSub[dfSub['username'] == uname].index, inplace=True) - # Rimuove la riga dalla tabella dfUsers che contiene 'uname' nel campo username. Con inplace = True modifico la tabella senza creare una copia + # Deletes the row from the dfUsers table that contains 'uname' in the username field. dfUsers.drop(dfUsers[dfUsers['username'] == uname].index, inplace=True) - # save the new csv + # saves the new .csv files dfSub.to_csv("./data/subscriptions.csv", index=False) dfUsers.to_csv("./data/users.csv", index=False) - print(f"'{uname}' removed sucessfully") - else: # if user not found + print(f"User {uname} deleted successfully") + else: # if user is not found print("username not found") ''' - Metodo: getSubscriptionsFor - Param: username - - - Ritorna il record del Dataframe che contiene il nome utente indicato e quindi tutte le sue iscrizioni +Method: getSubscriptionsFor +Param: username +- Returns the Dataframe record that contains the entered username and all its subscriptions ''' def getSubscriptionsFor(self,uname): df = self.getSubscriptionsDF() data = df[df['username'] == uname] - return data #Ritorna il record del Dataframe che contiene il nome utente indicato e quindi tutte le sue iscrizioni + return data ''' - Metodo: getSubscriptionsCategories - - - - Restituisce le colonne della tabella delle iscrizioni a partire dalla terza +Method: getSubscriptionsCategories +- Returns the columns of the subscriptions table starting from the third ''' def getSubscriptionsCategories(self): return self.getSubscriptionsDF().columns[2:] ''' - Metodo: subscribeUserToCategory - - - Inserisce il carattere 'y' nella colonna indicata dal parametro category - - Salva il dataframe nell'apposito file. - - +Method: subscribeUserToCategory + +- Inserts the 'y' character in the column indicated by the category parameter +- Save the dataframe in the appropriate file. ''' def subscribeUserToCategory(self,uname,category): - df = self.getSubscriptionsDF() #ottiene il Df delle iscrizioni - #Recupera il recordo con i dati dell'utente - df.loc[df.username == uname, category] = 'y'# inserisce 'y' alla colonna della categoria indicata nel record dell'utente indicato - print(df) - self.__saveSubscriptionsDF(df) # Chiama la funzione per salvare il file (to_csv) - print(f"{uname} successfully subscribed to {category}") + df = self.getSubscriptionsDF() # # gets the subscriptions dataframe + df.loc[df.username == uname, category] = 'y'# property that allows to locate the desired cell + # Inserts the 'y' character in the column indicated by the category parameter + self.__saveSubscriptionsDF(df) # calls the function to save the file (to_csv) + print(f"{uname} successfully subscribed to {category}") ''' - Metodo: unsubscribeUserToCategory - - - Inserisce il carattere 'n' nella colonna indicata dal parametro category - - Salva il dataframe nell'apposito file. - +Method: unsubscribeUserFromCategory +- Inserts the 'n' character in the column indicated by the category parameter +- Save the dataframe in the appropriate file. ''' - def unsubscribeUserToCategory(self, uname, category): - df = self.getSubscriptionsDF() - df.loc[df.username == uname, category] = 'n' # inserisce 'n' alla colonna della categoria indicata nel record dell'utente indicato + def unsubscribeUserFromCategory(self, uname, category): + df = self.getSubscriptionsDF() # gets the subscriptions dataframe + df.loc[df.username == uname, category] = 'n' # property that allows to locate the desired cell + # Inserts the 'n' character in the column indicated by the category parameter self.__saveSubscriptionsDF(df) - print("Unsubscribed successfully") + print("you unsubscribed successfully from this category") def __saveSubscriptionsDF(self,df): df.to_csv("./data/subscriptions.csv", index=False) @@ -199,60 +184,57 @@ class DatabaseManager: df.to_csv("./data/users.csv", index=False) ''' - Metodo: subscribeToAll - - - Inserisce il carattere 'n' in tutte le colonne della riga che si riferisce all'utente indicato - - Salva il dataframe nell'apposito file. - +Method: unsubscribefromAll +- Inserts the character 'n' in all columns of the row referring to the user. +- Save the dataframe in the appropriate file. ''' - def unsubscribeToAll(self, uname): - df = self.getSubscriptionsDF() #Ottiene il dataframe delle iscrizioni - row = df.loc[df.username == uname] #Prende il riferimento alla riga contenente i dati dell'utente - - for category in self.getSubscriptionsCategories(): #Per ogni colonna della tabella - row[category] = 'n' #Inserisce il carattere 'n' nelle colonna di quella specifica riga + def unsubscribeFromAll(self, uname): + df = self.getSubscriptionsDF() # gets the subscriptions dataframe - self.__saveSubscriptionsDF(df) #Salva + for category in self.getSubscriptionsCategories(): # for each column in the table + df.loc[df.username == uname, category] = 'n' # property that allows to locate the desired cell + # Inserts the 'n' character in the column indicated by the category parameter + self.__saveSubscriptionsDF(df) # saves changes + print("you unsubscribed successfully from all news categories") ''' - Metodo: userExists - Param: uname - - - Controlla se il nome utente inserito è contenuto in almeno un record della tabella +Method: userExists +Param: uname +- Checks if the entered username is contained in at least one record of the table ''' def userExists(self,uname): df = self.getUsersDF() - return df['username'].str.contains(uname).any() #any() serve a capire se esiste almeno un elemento qualsiasi dove la condizione di contains() è verificata + return df['username'].str.contains(uname).any() + # any () is used to determine if there is at least one element where the contains () condition is true ''' - Metodo: uregUser - Param: uname , name, email, password - - - Controlla se il nome utente inserito è contenuto in almeno un record della tabella - - Crea I dizionari relativi alla tabella utente e a quella iscrizioni - - Imposta i valori iniziali - - Inserisce in append i due record con i dati dell'utente e le sue iscrizioni - - Salva i due file csv - +Method: regUser +Param: uname , name, email, password + +- Checks if the username entered is contained in at least one record of the table +- Creates the dictionaries related to the users table and to the subscriptions table +- Sets initial values +- Inserts the two records with the user's data and his subscriptions using the append() method +- Save the two csv files ''' def regUser(self, uname,name, email,password): if not self.userExists(uname): - #Crea il dizionario che rappresenta il record con i dati dell'utente (andrà nella tabella DFUsers) + # Creates the dictionary that represents the record with the user data (it will go into the DFUsers table) udata = { "username": uname, "name": name, "password": password, } - #Crea il dizionario che rappresenta il record con i dati delle iscrizioni (andrà nella tabella DFSubscriptions) + # Creates the dictionary that represents the record with the subscriptions data (it will go into the DFSubscriptions table) sdata = { "username": uname, "email": email, @@ -270,19 +252,19 @@ class DatabaseManager: "religion": 'n', } - dfUsers = self.getUsersDF() # Prende un riferimento alla tabella DFUsers - dfSub = self.getSubscriptionsDF() # Prende un riferimento alla tabella DFSubscriptions + dfUsers = self.getUsersDF() # It takes a reference to the DFUsers table + dfSub = self.getSubscriptionsDF() # It takes a reference to the DFSubscriptions table - #Inserisce con il metodo append (all'ultimo elemento) il record con i dati dell'utente nella tabella DFUsers + # Inserts the user data records by using the append() method dfUsers = dfUsers.append(udata, ignore_index=True) self.__saveUsersDF(dfUsers) #salva - #Inserisce con il metodo append (all'ultimo elemento) il record con i dati delle iscrizioni nella tabella DFSub + # # Inserts the subscriptions data records by using the append() method dfSub = dfSub.append(sdata, ignore_index=True) self.__saveSubscriptionsDF(dfSub) #salva # output if everything completes - print("You are successfully registed but not Subscribed to any list. Please login to your account to select any subscription.") + print("You are successfully registed but not subscribed to any list. Please, login to your account to select any subscription.") else: print("Username already exists") diff --git a/EmailManager.py b/EmailManager.py index 8a58e47..6135154 100644 --- a/EmailManager.py +++ b/EmailManager.py @@ -1,3 +1,7 @@ +# Reference: How to send e-mails using Python +# https://www.youtube.com/watch?v=JRCJ6RtE3xU + + import smtplib # to connect to gmail api from email.message import EmailMessage # email formatting and reshaping from APIManager import APIManager @@ -10,52 +14,51 @@ class EmailManager: api = APIManager() # ---------------------- sends the email to a user - def sendEmailtoUser(self,email, subject, title, body, url): + def sendEmailtoUser(self, email, subject, title, body, url): EMAIL_ADDR = 'ema.univ@gmail.com' # email from EMAIL_PASS = 'Emaun1v2k21' # password - # enter the content, prettify + # enter the content and format content = f''' - News Alert - ----------------------------------------------- + News Alert +----------------------------------------------- - Title: {title} +Title: {title} - {body} +{body} - Reference url: {url} +Reference url: {url} ''' msg = EmailMessage() - msg['Subject'] = subject # adding title as email subject + msg['Subject'] = subject # adding email subject msg['From'] = EMAIL_ADDR # from email - msg['To'] = email # senders email - msg.set_content(content) # enter the content + msg['To'] = email # email recipient + msg.set_content(content) # email content with smtplib.SMTP_SSL("smtp.gmail.com", 465) as smtp: smtp.login(EMAIL_ADDR, EMAIL_PASS) # login to API smtp.send_message(msg) # send the msg - print(f"Email sent to {email} for {subject}") # print msg acknowledgement + print(f"Email sent to {email} for {subject}") # prints msg acknowledgement - # ---------------------- fectch emails and categories + # ---------------------- fetches emails and categories def sendEmails(self): - print('Its Email time') print(''' - ---------------------------- - Sending Emails - ---------------------------- +--------------------------- +e-mails sending in progress +--------------------------- ''') # import pandas as pd - df = self.dm.getSubscriptionsDF() # get subscription csv + df = self.dm.getSubscriptionsDF() # gets subscriptions .csv cats = ['business', 'finance', 'computer', 'games', 'entertainment', 'music', 'currentAffairs', 'health', 'lifestyle', 'sports', 'culture', 'religion'] for cat in cats: print(">>", cat) - title, body, url = self.api.getNews(cat) # get the news of ceertain category + title, body, url = self.api.getNews(cat) # gets the news based on category - for email in df[df[cat] == 'y']['email']: # if cat has 'y' variable - self.sendEmailtoUser(email, title, title, body, url) # send the email + for email in df[df[cat] == 'y']['email']: # if category has 'y' variable + self.sendEmailtoUser(email, title, title, body, url) # sends the email diff --git a/UserInterface.py b/UserInterface.py index 61555e4..87c2f99 100644 --- a/UserInterface.py +++ b/UserInterface.py @@ -1,67 +1,63 @@ -from Database import DatabaseManager +from Database import DatabaseManager # to manage data in .csv files using Pandas ''' -Classe utilizzata per simulare un interfaccia utente +Class used to simulate a user interface ''' class UserInterface: - dm = DatabaseManager() #Istanza del database manager utilizzata per le operazioni sui dati + dm = DatabaseManager() # instance of Database manager used for data operations ''' - Metodo: showMainMenu - - Presenta al terminale un'interfaccia all'avvio del programma che permette di scegliere le azioni da eseguire - + Method: MainMenu + At the start of the program It displays an interface that allows the user to choose the actions to perform ''' - def showMainMenu(self): + def mainMenu(self): menu = ''' - ------------------ MAIN MENU ---------------------- - Press following numbers to select - - 1- Admin (Manage Requests, Remove Users) - 2- Login - 3- Register - 4- Send Emails (Admin only) - 5- Exit - ---------------------------------------------------- +------------------ MAIN MENU ---------------------- +Press following numbers to select + +1 - Admin [ Users' subscriptions and management ] +2 - Login +3 - Sign up to News Service +4 - Send e-mails [ Admin only ] +5 - Exit +---------------------------------------------------- ''' - print(menu) # print it menu + print(menu) # prints the Main menu ''' - Metodo: showAdminMenu +Method: AdminMenu. - Presenta al terminale un'interfaccia per il pannello di controllo dell'amministratore di sistema, una volta che - l'amministratore ha effettuato l'accesso - - Permette di leggere le iscrizioni di tutti gli utenti ed eliminare gli utenti iscritti - ''' +It displays the system administrator control panel once the administrator is logged in. +It allows to read the subscriptions of all users and delete the subscribed users. + ''' - def showAdminMenu(self): + def adminMenu(self): while True: # print the menu menu = ''' - ------------------- ADMIN MENU --------------------- - Press following numbers to select +------------------- ADMIN MENU --------------------- +Press following numbers to select - 1- See all users' subscriptions - 2- Remove User - 3- Exit - ---------------------------------------------------- +1 - See all users' subscriptions +2 - Delete User +3 - Return to Main Menu +---------------------------------------------------- ''' print(menu) - _sel = int(input("> ")) # selt the input from menu + _sel = int(input("> ")) # - # shows all the database + # displays the subscription database if _sel == 1: self.dm.printSubscriptions() - # remove the specific user + # delete user elif _sel == 2: - uname = input("Enter username: ") # enter the username - self.dm.removeUser(uname) + uname = input("Enter username: ") # asks for the username to be deleted + self.dm.deleteUser(uname) elif _sel == 3: return @@ -69,100 +65,95 @@ class UserInterface: print("Wrong selection") ''' - Metodo: showUserMenu +Method: UserMenu. - Presenta al terminale un'interfaccia per il pannello di controllo dell'utente , una volta che ha effettuato l'accesso - - Permette di iscriversi o disiscriversi ai diversi topic di newsletter +Displays the user's control panel once they are logged in. +Allows user to subscribe or unsubscribe from news categories. ''' - def showUserMenu(self, uname): + def userMenu(self, uname): categories = self.dm.getSubscriptionsCategories() while True: # prints the menu menu = ''' - -------------------- USER MENU -------------------- - Press following numbers to select - - 1- See all subscriptions - 2- Subscribe to news feed - 3- Unsubscribe to news feed - 4- Unsubscribe to all News Feeds - 5- Exit - --------------------------------------------------- - +-------------------- USER MENU -------------------- +Press following numbers to select + +1 - View the news category you subscribed +2 - Subscribe to a news category +3 - Unsubscribe from a news category +4 - Unsubscribe from News Service +5 - Return to Main Menu +--------------------------------------------------- ''' print(menu) - _sel = int(input("> ")) # select the input + _sel = int(input("> ")) - # see all subscribed lists + # displays news categories subscribed by the user if _sel == 1: - userData = self.dm.getSubscriptionsFor(uname).to_dict('records')[0] # see all list by that user + userData = self.dm.getSubscriptionsFor(uname).to_dict('records')[0] + if 'y' not in userData.values(): # if there aren't active subscriptions + print('You have not yet subscribed to any news category \nPlease subscribe to one or more categories ') for k, v in userData.items(): if v == 'y': print(k, ":", "Subcribed") # print the keys and "subscribed" next to it - #df.to_csv("./data/subscriptions.csv", index=False) # save the change to file - # sub to new category + + # subscription to a news category elif _sel == 2: - print("You can subscribe to any of these categories \n", categories) # get all cols and print - catsel = input("type category (full): ") # select for the category + print("You can subscribe to any of these categories \n", categories) # gets all columns and print them + catsel = input("Please, type a news category: ") - if not catsel in categories: # if not in cols + if not catsel in categories: # if entered category is not in database columns print("invalid selection") - else: # else + else: self.dm.subscribeUserToCategory(uname,catsel) - # unsub to any cay + # unsubscription from a news category elif _sel == 3: - print("You can unsubscribe to any of these categories \n", categories) # show all cats - catsel = input("type category (full): ") # input the cat + print("Please, enter the news category you want to unsubscribe from \n", categories) # show all cats + catsel = input("Please, type a news category: ") # - if not catsel in categories: # if invalid selection + if not catsel in categories: # if entered category is not in database columns print("invalid selection") else: - self.dm.unsubscribeUserToCategory(uname,catsel) - + self.dm.unsubscribeUserFromCategory(uname, catsel) + # unsubscription from all news category elif _sel == 4: - self.dm.unsubscribeToAll(uname) + self.dm.unsubscribeFromAll(uname) elif _sel == 5: - return - else: print("Wrong selection") ''' - Metodo: showRegMenu - - Presenta al terminale un'interfaccia per le registrazione dell'utente - - Controlla l'esistenza del nuovo username e registra i nuovi dati +Method: RegMenu +Displays an interface for user registration. +Checks if the username already exists and saves the new data. ''' - def showRegMenu(self): - + def userSignUp(self): menu = ''' - -------------------- REGISTER MENU -------------------- - Press Enter your following details to Register yourself - ------------------------------------------------------- +-------------------- USER REGISTRATION ------------------ +Please enter your details to sign up to the News Service +--------------------------------------------------------- ''' - print(menu) # print the menu + print(menu) - # inputs user's informations - name = input("Name: ") # - uname = input("Username (unique): ") + # asks for user details + name = input("Name: ") + uname = input("Username (must be unique): ") - if self.dm.userExists(uname): # check if same username exists or not - print("Username already exists, Please choose different") # if yes then raise error + if self.dm.userExists(uname): # check if entered username exists + print("Username already exists, please choose a different one") # if it existas it raises an error return password = input("password: ") @@ -171,15 +162,13 @@ class UserInterface: self.dm.regUser(uname,name,email,password) ''' - Metodo: showLoginAdmin - - Presenta al terminale un'interfaccia per il login dell'amministratore - - Controlla la correttezza dei dati e restituisce True o False in base ad essa +Method: adminLogin. +Displays an interface for the administrator login. +Checks if entered data is correct and returns True or False. ''' - def showLoginAdmin(self): + def adminLogin(self): _user = input("username: ") _pass = input("Password: ") @@ -190,27 +179,26 @@ class UserInterface: ''' - Metodo: showLoginUser - - Presenta al terminale un'interfaccia per il login dell'utente - - Controlla la correttezza dei dati e restituisce True o False in base ad essa +Method: userLogin +Displays an interface for the user login. +Checks if entered data is correct and returns True or False. ''' - def showLoginUser(self): + def userLogin(self): df = self.dm.getUsersDF() _user = input('username: ') _pass = input('password: ') - if self.dm.userExists(_user): # Se il nome utente che hai inserito esiste - userData = df[df['username'] == _user] #Legge i dati relativi al nome utente che è stato inserito {"nome,""username","Password"} - if userData['password'].str.contains(_pass).any() : #Se la password che hai inserito è corretta - name = userData['name'] # get the name by username from csv file - print(f"welcome {name.to_string().split()[1]}") #Questa operazione sulla variabile name serve a prendere solo la seconda parola della stringa presente (nel caso abbia due nomi) - return True, _user # return true with name + if self.dm.userExists(_user): # if username exists + userData = df[df['username'] == _user] # reads user data {"name,""username","password"} + if userData['password'].str.contains(_pass).any() : # if typed password is correct + name = userData['name'] # get the name by username from .csv file + print(f"Welcome {name.to_string().split()[1]}") # This operation on the variable name is necessary + # to take only the second word of the string (in case it has two names) + return True, _user # returns true with name else: return False, None else: diff --git a/main.py b/main.py index 9b0ee21..e15d44c 100644 --- a/main.py +++ b/main.py @@ -1,55 +1,54 @@ -from Database import DatabaseManager -from EmailManager import EmailManager -from UserInterface import UserInterface -import pandas as pd -import sys +from Database import DatabaseManager # to manage data in .csv files using Pandas +from EmailManager import EmailManager # to send email to subscribed users +from UserInterface import UserInterface # to handle user interaction +import sys # for system calls (Exit) https://docs.python.org/3/library/sys.html def main(): - dm = DatabaseManager() # Si occupa delle operazioni sul DB - email = EmailManager() # Si occupa di inviare le email - ui = UserInterface() # Mostra i menù e chiede gli input + dm = DatabaseManager() # handles operations on Database + email = EmailManager() # send e-mails + ui = UserInterface() # shows menus and asks for input from user - dm.checkDatabaseExists() # checks for the database folder and database files exists or not. Creates the files of not exists - ui.showMainMenu() # shows the main menu + dm.checkDatabaseExists() # check if the database folder and database files are present or not. Create files if they don't exist + ui.mainMenu() # shows the main menu - select = int(input('>> ')) # waits for the input for 5mnts. + select = int(input('>> ')) - if select == 1: # Admin (Manage Requests, Remove Users) Apre il pannello Admin + if select == 1: # opens the admin panel - if ui.showLoginAdmin(): # if admin true + if ui.adminLogin(): # if admin true print("Welcome admin") - ui.showAdminMenu() # shows admin menu + ui.adminMenu() # shows admin menu else: - print("Wrong username or password please retry") # raise error + print("Wrong username or password, please retry") - elif select == 2: # Effettua il login dell'utente - re = ui.showLoginUser() # check if user exists re = (Esito, nomeUtente) - if re[0]: # Se il login va a buon fine - ui.showUserMenu(re[1]) # user menu + elif select == 2: # User login + re = ui.userLogin() # checks if user exists + if re[0]: # if login is successful + ui.userMenu(re[1]) # shows user menu else: print("User not exists or wrong password") # raises the error elif select == 3: - ui.showRegMenu() # registration menu and control panel + ui.userSignUp() # registration menu and control panel - elif select == 4: # Invia le email - re = ui.showLoginAdmin() # login admin - if re: # Se il login + elif select == 4: # sends e-mails + re = ui.adminLogin() # login admin + if re: # if login is successful print("Welcome admin") - email.sendEmails() # start sending the emails + email.sendEmails() # starts sending e-mails else: print("Wrong Username or Password") elif select == 5: - print("Bye...") # exits the system + print("Thanks for using News Service") # exits the system sys.exit() # exits the system -# Press the green button in the gutter to run the script. + if __name__ == '__main__': while True: main()