From 3bc5d3b5e4dc4a2c11ce504fd2af2f62cba9008a Mon Sep 17 00:00:00 2001 From: FelixR Date: Thu, 21 Feb 2019 21:53:48 +0000 Subject: [PATCH 01/41] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 697c2bf7..90e4c457 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ You should be using [Pipenv](https://pipenv.readthedocs.io/en/latest/). Take a l # Project Information -`# TODO` +TEAM GREEN GREENHOUSES ## Description From fc028d6e565ce5c0b297ebfbb9982788032180c4 Mon Sep 17 00:00:00 2001 From: Zomatree Date: Fri, 22 Feb 2019 03:52:24 +0000 Subject: [PATCH 02/41] set up basic framework setup a basic frame and added the frame of the login page --- project/client/gui.py | 49 +++++++++++++++++++++++++++++++ project/client/guiEXT/__init__.py | 0 project/client/guiEXT/login.py | 29 ++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 project/client/gui.py create mode 100644 project/client/guiEXT/__init__.py create mode 100644 project/client/guiEXT/login.py diff --git a/project/client/gui.py b/project/client/gui.py new file mode 100644 index 00000000..d0da45a7 --- /dev/null +++ b/project/client/gui.py @@ -0,0 +1,49 @@ +import tkinter as tk +from guiEXT import login + + +class App(tk.Tk): + """"the main application, subclassing Tk""" + def __init__(self): + """ + Initisizes the main application of the gui. + + Arguments: + None + + Returns: + the application. + """ + + super().__init__() + self.pages = { + login: login.Login(self) + } + #menubar = tk.Menu(self) + #filemenu = tk.Menu(menubar, tearoff=0) + #filemenu.add_command(label="Edit Profile") + #filemenu.add_command(label="Logout") +# + #menubar.add_cascade(label="Profile", menu=filemenu) +# + #self.config(menu=menubar) + self.change_page(login) + + def change_page(self, new_page): + """ + Change the currently displayed page. + + Arguments: + newFrame -- The frame to change to + """ + # Remove anything currently placed on the screen + for page in self.grid_slaves(): + if page.grid_info()["column"] == 0: + page.grid_forget() + # Place our new page onto the screen + self.pages[new_page].grid(row=0, column=0) + + +if __name__ == "__main__": + application = App() + application.mainloop() diff --git a/project/client/guiEXT/__init__.py b/project/client/guiEXT/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/project/client/guiEXT/login.py b/project/client/guiEXT/login.py new file mode 100644 index 00000000..0a9c4269 --- /dev/null +++ b/project/client/guiEXT/login.py @@ -0,0 +1,29 @@ +import tkinter as tk + + +class Login(tk.Frame): + """The login page for this application.""" + def __init__(self, parent): + """ + Initilises the login page. + + Parameters: + parent -- the main application + Returns: + the Login page. + """ + super().__init__() + self.title = tk.Label(self, text="Plase login") + self.username = tk.Entry(self) + self.password = tk.Entry(self, show="*") + self.username_label = tk.Label(self, text="Username:") + self.password_label = tk.Label(self, text="Password:") + self.login_button = tk.Button(self, text="Login") + + self.username.grid(row=2, column=1) + self.password.grid(row=3, column=1) + self.username_label.grid(row=2) + self.password_label.grid(row=3) + self.title.grid(row=0, column=1) + self.login_button.grid(row=4, column=1) + \ No newline at end of file From a79525908968a9d6cb772a68e7ba20a2cd9d672b Mon Sep 17 00:00:00 2001 From: FelixR Date: Sun, 24 Feb 2019 12:26:31 +0000 Subject: [PATCH 03/41] Base UI Updated .flake8 and Pipfile configs, Wrote initial code for UI. --- .flake8 | 1 + Pipfile | 3 ++- project/UI/application.py | 30 ++++++++++++++++++++++++++++++ project/__main__.py | 5 +++++ 4 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 project/UI/application.py diff --git a/.flake8 b/.flake8 index f2b41384..b1663a2f 100644 --- a/.flake8 +++ b/.flake8 @@ -1,3 +1,4 @@ +[flake8] max-line-length=100 application_import_names=projectt ignore=P102,B311,W503,E226,S311,W504,F821 diff --git a/Pipfile b/Pipfile index 72b70b6f..000bac1e 100644 --- a/Pipfile +++ b/Pipfile @@ -12,4 +12,5 @@ flake8 = "*" python_version = "3.7" [scripts] -lint = "python -m flake8" \ No newline at end of file +lint = "python -m flake8" +start = "python -m project" diff --git a/project/UI/application.py b/project/UI/application.py new file mode 100644 index 00000000..1b99e5fc --- /dev/null +++ b/project/UI/application.py @@ -0,0 +1,30 @@ +import tkinter as tk + +class Application(tk.Tk): + def __init__(self): + super().__init__() + + self.pages = {} + + self.create_pages() + + def create_pages(self): + self.pages[HomePage] = HomePage(self) + + self.change_page(HomePage) + + def change_page(self, new_page): + for page in self.grid_slaves(): + page.grid_remove() + + self.pages[new_page].grid(column=0, row=0) + +class HomePage(tk.Frame): + def __init__(self, parent): + super().__init__(parent) + + self.create_widgets() + + def create_widgets(self): + self.title = tk.Label(self, text="Hello World") + self.title.pack() diff --git a/project/__main__.py b/project/__main__.py index e69de29b..529061e0 100644 --- a/project/__main__.py +++ b/project/__main__.py @@ -0,0 +1,5 @@ +from .UI.application import Application + +if __name__ == "__main__": + app = Application() + app.mainloop() From 20116c611f5fef0d184427aa458123bd50c4ce92 Mon Sep 17 00:00:00 2001 From: Owen Throup <38217027+Throupy@users.noreply.github.com> Date: Sun, 24 Feb 2019 17:04:06 +0000 Subject: [PATCH 04/41] Added basic backend functionality -> Pulls calendar evetns from sqlite3 database -> Displays them with a small, basic tkinter GUI -> See the populate() function in DBHandler and add your events there. Next step is to add an "add event" GUI interface. --- backend/DBHandler.py | 45 +++++++++++++++++++ backend/calender.py | 103 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 backend/DBHandler.py create mode 100644 backend/calender.py diff --git a/backend/DBHandler.py b/backend/DBHandler.py new file mode 100644 index 00000000..86bf4ff8 --- /dev/null +++ b/backend/DBHandler.py @@ -0,0 +1,45 @@ +"""Database handling for calandar application.""" +import sqlite3 + + +class DBHandler: + """Database Handler Class.""" + + def __init__(self): + """Initialise the database connection. + + Arguments: + None + Returns: + None + """ + self.conn = sqlite3.connect("events.db") + self.cursor = self.conn.cursor() + self.cursor.execute(""" + CREATE TABLE IF NOT EXISTS events( + ID INTEGER PRIMARY KEY, + name TEXT, + location TEXT, + date TEXT, + description TEXT)""") + self.populate() + + def fetchEvents(self): + """Fetch event from the database.""" + self.cursor.execute("""SELECT * FROM events""") + # Fetch rows + rows = self.cursor.fetchall() + return rows + + # TESTING - ONLY USED IN DEVELOPMENT. REMOVE UPON RELEASE!!! + def populate(self): + """Use to populate the database with sample data.""" + self.cursor.execute("""INSERT INTO events(name,location, + description,date) + VALUES(?,?,?,?)""", + ("Meeting", + "Office on 4th street", + "Talk about upcoming work events", + "03/03/2020") + ) + self.conn.commit() diff --git a/backend/calender.py b/backend/calender.py new file mode 100644 index 00000000..8a0d40e9 --- /dev/null +++ b/backend/calender.py @@ -0,0 +1,103 @@ +"""Calendar application for OOP tkinter.""" +import tkinter as tk +from DBHandler import DBHandler + + +class Application(tk.Tk): + """Application class inheriting from tk.Tk.""" + + def __init__(self): + """ + Initialise the Application class. + + Arguments: + None + Returns: + None + """ + self.dbh = DBHandler() + super().__init__() + + self.create_pages() + + def create_pages(self): + """ + Create the pages used inside the application. + + Arguments: + None + Returns: + None + """ + self.pages = {} + + self.pages[CalendarPage] = CalendarPage(self) + + self.change_page(CalendarPage) + + def change_page(self, new_page): + """ + Change the currently displayed page. + + Arguments: + newFrame -- The frame to change to + """ + # Remove anything currently placed on the screen + for page in self.grid_slaves(): + if page.grid_info()["column"] == 0: + page.grid_forget() + # Place our new page onto the screen + self.pages[new_page].grid(row=0, column=0) + + +class CalendarPage(tk.Frame): + """Example page for Application.""" + + eventLabels = { + 0: "ID", + 1: "Name", + 2: "Location", + 3: "Date", + 4: "Description" + } + + def __init__(self, parent): + """ + Initialise the Example page. + + Arguments: + None + Returns: + None + """ + super().__init__() + self.parent = parent + self.create_widgets() + + def create_widgets(self): + """ + Create the pages widgets. + + Arguments: + None + Returns: + None + """ + # Fetch all events + events = self.parent.dbh.fetchEvents() + print(events) + # Event format: + # (ID, name, location, description)-- + for event in events: + string = "" + for value in event: + string += self.eventLabels[event.index(value)] + " - " + string += str(value) + "\n" + eventPanel = tk.PanedWindow(self, bd=5, relief="sunken", width=600) + eventPanel.grid() + eventPanel.add(tk.Label(self, text=string)) + + +if __name__ == "__main__": + app = Application() + app.mainloop() From fef8af01f05805606b971c14691e0202ce06ea39 Mon Sep 17 00:00:00 2001 From: Owen Throup <38217027+Throupy@users.noreply.github.com> Date: Sun, 24 Feb 2019 17:05:48 +0000 Subject: [PATCH 05/41] Moved folder I'm a silly boy. --- {backend => project/backend}/DBHandler.py | 0 {backend => project/backend}/calender.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename {backend => project/backend}/DBHandler.py (100%) rename {backend => project/backend}/calender.py (100%) diff --git a/backend/DBHandler.py b/project/backend/DBHandler.py similarity index 100% rename from backend/DBHandler.py rename to project/backend/DBHandler.py diff --git a/backend/calender.py b/project/backend/calender.py similarity index 100% rename from backend/calender.py rename to project/backend/calender.py From 0f88d6c024123083b547d2059c50d8a95b267f31 Mon Sep 17 00:00:00 2001 From: Zomatree Date: Sun, 24 Feb 2019 17:30:42 +0000 Subject: [PATCH 06/41] remove old project files --- .gitignore | 2 ++ project/client/gui.py | 49 ------------------------------- project/client/guiEXT/__init__.py | 0 project/client/guiEXT/login.py | 29 ------------------ 4 files changed, 2 insertions(+), 78 deletions(-) delete mode 100644 project/client/gui.py delete mode 100644 project/client/guiEXT/__init__.py delete mode 100644 project/client/guiEXT/login.py diff --git a/.gitignore b/.gitignore index 894a44cc..35aa063e 100644 --- a/.gitignore +++ b/.gitignore @@ -102,3 +102,5 @@ venv.bak/ # mypy .mypy_cache/ +project/CODEJAM-4-26a1748ad4a6.json +.gitignore diff --git a/project/client/gui.py b/project/client/gui.py deleted file mode 100644 index d0da45a7..00000000 --- a/project/client/gui.py +++ /dev/null @@ -1,49 +0,0 @@ -import tkinter as tk -from guiEXT import login - - -class App(tk.Tk): - """"the main application, subclassing Tk""" - def __init__(self): - """ - Initisizes the main application of the gui. - - Arguments: - None - - Returns: - the application. - """ - - super().__init__() - self.pages = { - login: login.Login(self) - } - #menubar = tk.Menu(self) - #filemenu = tk.Menu(menubar, tearoff=0) - #filemenu.add_command(label="Edit Profile") - #filemenu.add_command(label="Logout") -# - #menubar.add_cascade(label="Profile", menu=filemenu) -# - #self.config(menu=menubar) - self.change_page(login) - - def change_page(self, new_page): - """ - Change the currently displayed page. - - Arguments: - newFrame -- The frame to change to - """ - # Remove anything currently placed on the screen - for page in self.grid_slaves(): - if page.grid_info()["column"] == 0: - page.grid_forget() - # Place our new page onto the screen - self.pages[new_page].grid(row=0, column=0) - - -if __name__ == "__main__": - application = App() - application.mainloop() diff --git a/project/client/guiEXT/__init__.py b/project/client/guiEXT/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/project/client/guiEXT/login.py b/project/client/guiEXT/login.py deleted file mode 100644 index 0a9c4269..00000000 --- a/project/client/guiEXT/login.py +++ /dev/null @@ -1,29 +0,0 @@ -import tkinter as tk - - -class Login(tk.Frame): - """The login page for this application.""" - def __init__(self, parent): - """ - Initilises the login page. - - Parameters: - parent -- the main application - Returns: - the Login page. - """ - super().__init__() - self.title = tk.Label(self, text="Plase login") - self.username = tk.Entry(self) - self.password = tk.Entry(self, show="*") - self.username_label = tk.Label(self, text="Username:") - self.password_label = tk.Label(self, text="Password:") - self.login_button = tk.Button(self, text="Login") - - self.username.grid(row=2, column=1) - self.password.grid(row=3, column=1) - self.username_label.grid(row=2) - self.password_label.grid(row=3) - self.title.grid(row=0, column=1) - self.login_button.grid(row=4, column=1) - \ No newline at end of file From 0eacc3e7babd8f36f56b56cc4af65159bd6f6bca Mon Sep 17 00:00:00 2001 From: Owen Throup <38217027+Throupy@users.noreply.github.com> Date: Sun, 24 Feb 2019 19:03:59 +0000 Subject: [PATCH 07/41] Throupy (#1) * Added basic backend functionality -> Pulls calendar evetns from sqlite3 database -> Displays them with a small, basic tkinter GUI -> See the populate() function in DBHandler and add your events there. Next step is to add an "add event" GUI interface. * Moved folder I'm a silly boy. --- project/backend/DBHandler.py | 45 +++++++++++++++ project/backend/calender.py | 103 +++++++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 project/backend/DBHandler.py create mode 100644 project/backend/calender.py diff --git a/project/backend/DBHandler.py b/project/backend/DBHandler.py new file mode 100644 index 00000000..86bf4ff8 --- /dev/null +++ b/project/backend/DBHandler.py @@ -0,0 +1,45 @@ +"""Database handling for calandar application.""" +import sqlite3 + + +class DBHandler: + """Database Handler Class.""" + + def __init__(self): + """Initialise the database connection. + + Arguments: + None + Returns: + None + """ + self.conn = sqlite3.connect("events.db") + self.cursor = self.conn.cursor() + self.cursor.execute(""" + CREATE TABLE IF NOT EXISTS events( + ID INTEGER PRIMARY KEY, + name TEXT, + location TEXT, + date TEXT, + description TEXT)""") + self.populate() + + def fetchEvents(self): + """Fetch event from the database.""" + self.cursor.execute("""SELECT * FROM events""") + # Fetch rows + rows = self.cursor.fetchall() + return rows + + # TESTING - ONLY USED IN DEVELOPMENT. REMOVE UPON RELEASE!!! + def populate(self): + """Use to populate the database with sample data.""" + self.cursor.execute("""INSERT INTO events(name,location, + description,date) + VALUES(?,?,?,?)""", + ("Meeting", + "Office on 4th street", + "Talk about upcoming work events", + "03/03/2020") + ) + self.conn.commit() diff --git a/project/backend/calender.py b/project/backend/calender.py new file mode 100644 index 00000000..8a0d40e9 --- /dev/null +++ b/project/backend/calender.py @@ -0,0 +1,103 @@ +"""Calendar application for OOP tkinter.""" +import tkinter as tk +from DBHandler import DBHandler + + +class Application(tk.Tk): + """Application class inheriting from tk.Tk.""" + + def __init__(self): + """ + Initialise the Application class. + + Arguments: + None + Returns: + None + """ + self.dbh = DBHandler() + super().__init__() + + self.create_pages() + + def create_pages(self): + """ + Create the pages used inside the application. + + Arguments: + None + Returns: + None + """ + self.pages = {} + + self.pages[CalendarPage] = CalendarPage(self) + + self.change_page(CalendarPage) + + def change_page(self, new_page): + """ + Change the currently displayed page. + + Arguments: + newFrame -- The frame to change to + """ + # Remove anything currently placed on the screen + for page in self.grid_slaves(): + if page.grid_info()["column"] == 0: + page.grid_forget() + # Place our new page onto the screen + self.pages[new_page].grid(row=0, column=0) + + +class CalendarPage(tk.Frame): + """Example page for Application.""" + + eventLabels = { + 0: "ID", + 1: "Name", + 2: "Location", + 3: "Date", + 4: "Description" + } + + def __init__(self, parent): + """ + Initialise the Example page. + + Arguments: + None + Returns: + None + """ + super().__init__() + self.parent = parent + self.create_widgets() + + def create_widgets(self): + """ + Create the pages widgets. + + Arguments: + None + Returns: + None + """ + # Fetch all events + events = self.parent.dbh.fetchEvents() + print(events) + # Event format: + # (ID, name, location, description)-- + for event in events: + string = "" + for value in event: + string += self.eventLabels[event.index(value)] + " - " + string += str(value) + "\n" + eventPanel = tk.PanedWindow(self, bd=5, relief="sunken", width=600) + eventPanel.grid() + eventPanel.add(tk.Label(self, text=string)) + + +if __name__ == "__main__": + app = Application() + app.mainloop() From d2d642b1392fb2461fb3c6e40f3fa0ebbfeedffc Mon Sep 17 00:00:00 2001 From: Owen Throup <38217027+Throupy@users.noreply.github.com> Date: Sun, 24 Feb 2019 21:46:09 +0000 Subject: [PATCH 08/41] Added Add event option and menu -> You can now add an event with a click of a button -> Simple GUI, needs improving -> Next task is to remove events --- project/backend/DBHandler.py | 30 +++++++++----- project/backend/calender.py | 74 ++++++++++++++++++++++++++++++++++- project/backend/events.db | Bin 0 -> 8192 bytes 3 files changed, 94 insertions(+), 10 deletions(-) create mode 100644 project/backend/events.db diff --git a/project/backend/DBHandler.py b/project/backend/DBHandler.py index 86bf4ff8..11180f8e 100644 --- a/project/backend/DBHandler.py +++ b/project/backend/DBHandler.py @@ -22,7 +22,7 @@ def __init__(self): location TEXT, date TEXT, description TEXT)""") - self.populate() + # self.populate() def fetchEvents(self): """Fetch event from the database.""" @@ -31,15 +31,27 @@ def fetchEvents(self): rows = self.cursor.fetchall() return rows + def addEvent(self, name, location, date, description): + """Create a new event and add it to the database.""" + self.cursor.execute('''INSERT INTO users(name,location, + date,description) + VALUES(?,?,?)''', (name, + location, + date, + description + ) + ) + self.db.commit() + # TESTING - ONLY USED IN DEVELOPMENT. REMOVE UPON RELEASE!!! def populate(self): """Use to populate the database with sample data.""" - self.cursor.execute("""INSERT INTO events(name,location, - description,date) - VALUES(?,?,?,?)""", - ("Meeting", - "Office on 4th street", - "Talk about upcoming work events", - "03/03/2020") - ) + self.cursor.execute(""" INSERT INTO events + (name,location, + description,date) + VALUES(?,?,?,?)""", ("Meeting", + "Office on 4th street", + """Talk about upcoming + work events""", + "03/03/2020")) self.conn.commit() diff --git a/project/backend/calender.py b/project/backend/calender.py index 8a0d40e9..eeef730b 100644 --- a/project/backend/calender.py +++ b/project/backend/calender.py @@ -31,6 +31,7 @@ def create_pages(self): """ self.pages = {} + self.pages[AddEventPage] = AddEventPage(self) self.pages[CalendarPage] = CalendarPage(self) self.change_page(CalendarPage) @@ -83,9 +84,15 @@ def create_widgets(self): Returns: None """ + # Create an add event button + self.addEventBtn = tk.Button(self, + text="[+] Add event", + command=lambda: self.parent.change_page( + AddEventPage + )) + self.addEventBtn.grid() # Fetch all events events = self.parent.dbh.fetchEvents() - print(events) # Event format: # (ID, name, location, description)-- for event in events: @@ -98,6 +105,71 @@ def create_widgets(self): eventPanel.add(tk.Label(self, text=string)) +class AddEventPage(tk.Frame): + """Page where you can add events to the calendar.""" + + def __init__(self, parent): + """ + Initialise the Add Event page. + + Arguments: + None + Returns: + None + """ + super().__init__() + self.parent = parent + self.create_widgets() + + def create_widgets(self): + """ + Create the pages widgets. + + Arguments: + None + Returns: + None + """ + self.title = tk.Label(self, text="Add an event", font=(30)) + self.title.grid(column=1) + # Name + self.name = tk.Label(self, text="Name", font=(24)) + self.name.grid(row=1, sticky="E") + self.nameEntry = tk.Entry(self) + self.nameEntry.grid(row=1, column=1) + # Location + self.location = tk.Label(self, text="Location", font=(24)) + self.location.grid(row=2, sticky="E") + self.locationEntry = tk.Entry(self) + self.locationEntry.grid(row=2, column=1) + # Date + self.date = tk.Label(self, text="Date", font=(24)) + self.date.grid(row=3, sticky="E") + self.dateEntry = tk.Entry(self) + self.dateEntry.grid(row=3, column=1) + # Description + self.description = tk.Label(self, text="Description", font=(24)) + self.description.grid(row=4, sticky="E") + self.descriptionEntry = tk.Text(self, height=5, width=15) + self.descriptionEntry.grid(row=4, column=1) + # Submit Button + if len(self.nameEntry.get()) == 0 or \ + len(self.locationEntry.get()) == 0 or \ + len(self.dateEntry.get()) == 0 or \ + len(self.descriptionEntry.get("1.0")) == 0: + # Need some sort of UI goodness here! + print("[AddEventPage] Not all boxes filled") + self.submitBtn = tk.Button(self, + text="Submit ✔", + command=lambda: self.parent.dbh.addEvent( + self.nameEntry.get(), + self.locationEntry.get(), + self.dateEntry.get(), + self.descriptionEntry.get("1.0") + )) + self.submitBtn.grid() + + if __name__ == "__main__": app = Application() app.mainloop() diff --git a/project/backend/events.db b/project/backend/events.db new file mode 100644 index 0000000000000000000000000000000000000000..7b774c0faaad34fd4ba1fb6386cc21b835f081a4 GIT binary patch literal 8192 zcmeI$yH3L}6b4{BMIa%eutCLg*g!%MTG%OIp|mNNkb#bF>d>f3TqQ2d@Ju`ekA?& zU)Ss{?jADR5D1Rwwb2tWV=5P$##AOL~?A@CINm5q9xKUYTfGo>C>VXE2aoQ0wl z35r^$fuPym&MJKh|D62GNL+}Ju0y}u3VYNMy}gBdh0GO2;x1Y|%5*GEs*7)q2hvvb zUuO+51xi5A=KmY;|fB*y_009U<00Izz00bcLD}lDN%(jlVJ6)wr zTHIeHNg6A%CH#>YQe{fJ?KKZ Date: Sun, 24 Feb 2019 21:55:46 +0000 Subject: [PATCH 09/41] Throupy (#2) * Added basic backend functionality -> Pulls calendar evetns from sqlite3 database -> Displays them with a small, basic tkinter GUI -> See the populate() function in DBHandler and add your events there. Next step is to add an "add event" GUI interface. * Moved folder I'm a silly boy. * Added Add event option and menu -> You can now add an event with a click of a button -> Simple GUI, needs improving -> Next task is to remove events --- project/backend/DBHandler.py | 31 ++++++++++---- project/backend/calender.py | 77 ++++++++++++++++++++++++++++++++++- project/backend/events.db | Bin 0 -> 8192 bytes 3 files changed, 98 insertions(+), 10 deletions(-) create mode 100644 project/backend/events.db diff --git a/project/backend/DBHandler.py b/project/backend/DBHandler.py index 86bf4ff8..db841620 100644 --- a/project/backend/DBHandler.py +++ b/project/backend/DBHandler.py @@ -22,7 +22,9 @@ def __init__(self): location TEXT, date TEXT, description TEXT)""") - self.populate() + + # self.populate() + def fetchEvents(self): """Fetch event from the database.""" @@ -31,15 +33,26 @@ def fetchEvents(self): rows = self.cursor.fetchall() return rows + def addEvent(self, name, location, date, description): + """Create a new event and add it to the database.""" + self.cursor.execute('''INSERT INTO users(name,location, + date,description) + VALUES(?,?,?)''', (name, + location, + date, + description + ) + ) + self.db.commit() + # TESTING - ONLY USED IN DEVELOPMENT. REMOVE UPON RELEASE!!! def populate(self): """Use to populate the database with sample data.""" - self.cursor.execute("""INSERT INTO events(name,location, - description,date) - VALUES(?,?,?,?)""", - ("Meeting", - "Office on 4th street", - "Talk about upcoming work events", - "03/03/2020") - ) + self.cursor.execute(""" INSERT INTO events + (name,location, + description,date) + VALUES(?,?,?,?)""", ("Meeting", + "Office on 4th street", + """Talk about upcoming + work events""", self.conn.commit() diff --git a/project/backend/calender.py b/project/backend/calender.py index 8a0d40e9..5a707c84 100644 --- a/project/backend/calender.py +++ b/project/backend/calender.py @@ -30,6 +30,8 @@ def create_pages(self): None """ self.pages = {} + + self.pages[AddEventPage] = AddEventPage(self) self.pages[CalendarPage] = CalendarPage(self) @@ -83,9 +85,17 @@ def create_widgets(self): Returns: None """ + + # Create an add event button + self.addEventBtn = tk.Button(self, + text="[+] Add event", + command=lambda: self.parent.change_page( + AddEventPage + )) + self.addEventBtn.grid() # Fetch all events events = self.parent.dbh.fetchEvents() - print(events) + # Event format: # (ID, name, location, description)-- for event in events: @@ -98,6 +108,71 @@ def create_widgets(self): eventPanel.add(tk.Label(self, text=string)) + +class AddEventPage(tk.Frame): + """Page where you can add events to the calendar.""" + + def __init__(self, parent): + """ + Initialise the Add Event page. + + Arguments: + None + Returns: + None + """ + super().__init__() + self.parent = parent + self.create_widgets() + + def create_widgets(self): + """ + Create the pages widgets. + + Arguments: + None + Returns: + None + """ + self.title = tk.Label(self, text="Add an event", font=(30)) + self.title.grid(column=1) + # Name + self.name = tk.Label(self, text="Name", font=(24)) + self.name.grid(row=1, sticky="E") + self.nameEntry = tk.Entry(self) + self.nameEntry.grid(row=1, column=1) + # Location + self.location = tk.Label(self, text="Location", font=(24)) + self.location.grid(row=2, sticky="E") + self.locationEntry = tk.Entry(self) + self.locationEntry.grid(row=2, column=1) + # Date + self.date = tk.Label(self, text="Date", font=(24)) + self.date.grid(row=3, sticky="E") + self.dateEntry = tk.Entry(self) + self.dateEntry.grid(row=3, column=1) + # Description + self.description = tk.Label(self, text="Description", font=(24)) + self.description.grid(row=4, sticky="E") + self.descriptionEntry = tk.Text(self, height=5, width=15) + self.descriptionEntry.grid(row=4, column=1) + # Submit Button + if len(self.nameEntry.get()) == 0 or \ + len(self.locationEntry.get()) == 0 or \ + len(self.dateEntry.get()) == 0 or \ + len(self.descriptionEntry.get("1.0")) == 0: + # Need some sort of UI goodness here! + print("[AddEventPage] Not all boxes filled") + self.submitBtn = tk.Button(self, + text="Submit ✔", + command=lambda: self.parent.dbh.addEvent( + self.nameEntry.get(), + self.locationEntry.get(), + self.dateEntry.get(), + self.descriptionEntry.get("1.0") + )) + self.submitBtn.grid() + if __name__ == "__main__": app = Application() app.mainloop() diff --git a/project/backend/events.db b/project/backend/events.db new file mode 100644 index 0000000000000000000000000000000000000000..7b774c0faaad34fd4ba1fb6386cc21b835f081a4 GIT binary patch literal 8192 zcmeI$yH3L}6b4{BMIa%eutCLg*g!%MTG%OIp|mNNkb#bF>d>f3TqQ2d@Ju`ekA?& zU)Ss{?jADR5D1Rwwb2tWV=5P$##AOL~?A@CINm5q9xKUYTfGo>C>VXE2aoQ0wl z35r^$fuPym&MJKh|D62GNL+}Ju0y}u3VYNMy}gBdh0GO2;x1Y|%5*GEs*7)q2hvvb zUuO+51xi5A=KmY;|fB*y_009U<00Izz00bcLD}lDN%(jlVJ6)wr zTHIeHNg6A%CH#>YQe{fJ?KKZ Date: Sun, 24 Feb 2019 21:56:53 +0000 Subject: [PATCH 10/41] Added hound.yml --- .hound.yml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .hound.yml diff --git a/.hound.yml b/.hound.yml new file mode 100644 index 00000000..09d8c1ba --- /dev/null +++ b/.hound.yml @@ -0,0 +1,3 @@ +flake8: + enabled: true + config_file: .flake8 From c7623912a914fff571a74b6716d7b7c2a6dc6fb1 Mon Sep 17 00:00:00 2001 From: Owen Throup <38217027+Throupy@users.noreply.github.com> Date: Sun, 24 Feb 2019 21:57:56 +0000 Subject: [PATCH 11/41] Split up pages Created a new file for each of the application's pages. --- project/backend/DBHandler.py | 2 +- project/backend/calender.py | 120 +------------------------- project/backend/pages/addeventpage.py | 68 +++++++++++++++ project/backend/pages/calendarpage.py | 57 ++++++++++++ 4 files changed, 128 insertions(+), 119 deletions(-) create mode 100644 project/backend/pages/addeventpage.py create mode 100644 project/backend/pages/calendarpage.py diff --git a/project/backend/DBHandler.py b/project/backend/DBHandler.py index 11180f8e..1b742524 100644 --- a/project/backend/DBHandler.py +++ b/project/backend/DBHandler.py @@ -33,7 +33,7 @@ def fetchEvents(self): def addEvent(self, name, location, date, description): """Create a new event and add it to the database.""" - self.cursor.execute('''INSERT INTO users(name,location, + self.cursor.execute('''INSERT INTO events(name,location, date,description) VALUES(?,?,?)''', (name, location, diff --git a/project/backend/calender.py b/project/backend/calender.py index eeef730b..af3756b3 100644 --- a/project/backend/calender.py +++ b/project/backend/calender.py @@ -1,6 +1,8 @@ """Calendar application for OOP tkinter.""" import tkinter as tk from DBHandler import DBHandler +from pages.addeventpage import AddEventPage +from pages.calendarpage import CalendarPage class Application(tk.Tk): @@ -51,124 +53,6 @@ def change_page(self, new_page): self.pages[new_page].grid(row=0, column=0) -class CalendarPage(tk.Frame): - """Example page for Application.""" - - eventLabels = { - 0: "ID", - 1: "Name", - 2: "Location", - 3: "Date", - 4: "Description" - } - - def __init__(self, parent): - """ - Initialise the Example page. - - Arguments: - None - Returns: - None - """ - super().__init__() - self.parent = parent - self.create_widgets() - - def create_widgets(self): - """ - Create the pages widgets. - - Arguments: - None - Returns: - None - """ - # Create an add event button - self.addEventBtn = tk.Button(self, - text="[+] Add event", - command=lambda: self.parent.change_page( - AddEventPage - )) - self.addEventBtn.grid() - # Fetch all events - events = self.parent.dbh.fetchEvents() - # Event format: - # (ID, name, location, description)-- - for event in events: - string = "" - for value in event: - string += self.eventLabels[event.index(value)] + " - " - string += str(value) + "\n" - eventPanel = tk.PanedWindow(self, bd=5, relief="sunken", width=600) - eventPanel.grid() - eventPanel.add(tk.Label(self, text=string)) - - -class AddEventPage(tk.Frame): - """Page where you can add events to the calendar.""" - - def __init__(self, parent): - """ - Initialise the Add Event page. - - Arguments: - None - Returns: - None - """ - super().__init__() - self.parent = parent - self.create_widgets() - - def create_widgets(self): - """ - Create the pages widgets. - - Arguments: - None - Returns: - None - """ - self.title = tk.Label(self, text="Add an event", font=(30)) - self.title.grid(column=1) - # Name - self.name = tk.Label(self, text="Name", font=(24)) - self.name.grid(row=1, sticky="E") - self.nameEntry = tk.Entry(self) - self.nameEntry.grid(row=1, column=1) - # Location - self.location = tk.Label(self, text="Location", font=(24)) - self.location.grid(row=2, sticky="E") - self.locationEntry = tk.Entry(self) - self.locationEntry.grid(row=2, column=1) - # Date - self.date = tk.Label(self, text="Date", font=(24)) - self.date.grid(row=3, sticky="E") - self.dateEntry = tk.Entry(self) - self.dateEntry.grid(row=3, column=1) - # Description - self.description = tk.Label(self, text="Description", font=(24)) - self.description.grid(row=4, sticky="E") - self.descriptionEntry = tk.Text(self, height=5, width=15) - self.descriptionEntry.grid(row=4, column=1) - # Submit Button - if len(self.nameEntry.get()) == 0 or \ - len(self.locationEntry.get()) == 0 or \ - len(self.dateEntry.get()) == 0 or \ - len(self.descriptionEntry.get("1.0")) == 0: - # Need some sort of UI goodness here! - print("[AddEventPage] Not all boxes filled") - self.submitBtn = tk.Button(self, - text="Submit ✔", - command=lambda: self.parent.dbh.addEvent( - self.nameEntry.get(), - self.locationEntry.get(), - self.dateEntry.get(), - self.descriptionEntry.get("1.0") - )) - self.submitBtn.grid() - if __name__ == "__main__": app = Application() diff --git a/project/backend/pages/addeventpage.py b/project/backend/pages/addeventpage.py new file mode 100644 index 00000000..2e6e4dfa --- /dev/null +++ b/project/backend/pages/addeventpage.py @@ -0,0 +1,68 @@ +"""Add event page for the calendar application.""" +import tkinter as tk + + +class AddEventPage(tk.Frame): + """Page where you can add events to the calendar.""" + + def __init__(self, parent): + """ + Initialise the Add Event page. + + Arguments: + None + Returns: + None + """ + super().__init__() + self.parent = parent + self.create_widgets() + + def create_widgets(self): + """ + Create the pages widgets. + + Arguments: + None + Returns: + None + """ + self.title = tk.Label(self, text="Add an event", font=(30)) + self.title.grid(column=1) + # Name + self.name = tk.Label(self, text="Name", font=(24)) + self.name.grid(row=1, sticky="E") + self.nameEntry = tk.Entry(self) + self.nameEntry.grid(row=1, column=1) + # Location + self.location = tk.Label(self, text="Location", font=(24)) + self.location.grid(row=2, sticky="E") + self.locationEntry = tk.Entry(self) + self.locationEntry.grid(row=2, column=1) + # Date + self.date = tk.Label(self, text="Date", font=(24)) + self.date.grid(row=3, sticky="E") + self.dateEntry = tk.Entry(self) + self.dateEntry.grid(row=3, column=1) + # Description + self.description = tk.Label(self, text="Description", font=(24)) + self.description.grid(row=4, sticky="E") + self.descriptionEntry = tk.Text(self, height=5, width=15) + self.descriptionEntry.grid(row=4, column=1) + # Submit Button + if len(self.nameEntry.get()) == 0 or \ + len(self.locationEntry.get()) == 0 or \ + len(self.dateEntry.get()) == 0 or \ + len(self.descriptionEntry.get("1.0")) == 0: + # Need some sort of UI goodness here! + print("[AddEventPage] Not all boxes filled") + # Break out + self.submitBtn = tk.Button(self, + text="Submit ✔", + command=lambda: self.parent.dbh.addEvent( + self.nameEntry.get(), + self.locationEntry.get(), + self.dateEntry.get(), + self.descriptionEntry.get("1.0") + )) + self.submitBtn.grid() diff --git a/project/backend/pages/calendarpage.py b/project/backend/pages/calendarpage.py new file mode 100644 index 00000000..4d57a4b0 --- /dev/null +++ b/project/backend/pages/calendarpage.py @@ -0,0 +1,57 @@ +"""Main page for the calendar application.""" +import tkinter as tk +from pages.addeventpage import AddEventPage + + +class CalendarPage(tk.Frame): + """Example page for Application.""" + + eventLabels = { + 0: "ID", + 1: "Name", + 2: "Location", + 3: "Date", + 4: "Description" + } + + def __init__(self, parent): + """ + Initialise the Example page. + + Arguments: + None + Returns: + None + """ + super().__init__() + self.parent = parent + self.create_widgets() + + def create_widgets(self): + """ + Create the pages widgets. + + Arguments: + None + Returns: + None + """ + # Create an add event button + self.addEventBtn = tk.Button(self, + text="[+] Add event", + command=lambda: self.parent.change_page( + AddEventPage + )) + self.addEventBtn.grid() + # Fetch all events + events = self.parent.dbh.fetchEvents() + # Event format: + # (ID, name, location, description)-- + for event in events: + string = "" + for value in event: + string += self.eventLabels[event.index(value)] + " - " + string += str(value) + "\n" + eventPanel = tk.PanedWindow(self, bd=5, relief="sunken", width=600) + eventPanel.grid() + eventPanel.add(tk.Label(self, text=string)) From 6175a6811667559441e92e434dadeaba98450fc8 Mon Sep 17 00:00:00 2001 From: Owen Throup <38217027+Throupy@users.noreply.github.com> Date: Sun, 24 Feb 2019 22:05:15 +0000 Subject: [PATCH 12/41] Throupy (#3) * Added basic backend functionality -> Pulls calendar evetns from sqlite3 database -> Displays them with a small, basic tkinter GUI -> See the populate() function in DBHandler and add your events there. Next step is to add an "add event" GUI interface. * Moved folder I'm a silly boy. * Added Add event option and menu -> You can now add an event with a click of a button -> Simple GUI, needs improving -> Next task is to remove events * Split up pages Created a new file for each of the application's pages. --- project/backend/DBHandler.py | 3 +- project/backend/calender.py | 125 +------------------------- project/backend/pages/addeventpage.py | 68 ++++++++++++++ project/backend/pages/calendarpage.py | 57 ++++++++++++ 4 files changed, 131 insertions(+), 122 deletions(-) create mode 100644 project/backend/pages/addeventpage.py create mode 100644 project/backend/pages/calendarpage.py diff --git a/project/backend/DBHandler.py b/project/backend/DBHandler.py index db841620..3e7d3445 100644 --- a/project/backend/DBHandler.py +++ b/project/backend/DBHandler.py @@ -35,6 +35,7 @@ def fetchEvents(self): def addEvent(self, name, location, date, description): """Create a new event and add it to the database.""" + self.cursor.execute('''INSERT INTO users(name,location, date,description) VALUES(?,?,?)''', (name, @@ -54,5 +55,5 @@ def populate(self): VALUES(?,?,?,?)""", ("Meeting", "Office on 4th street", """Talk about upcoming - work events""", + work events""",)) self.conn.commit() diff --git a/project/backend/calender.py b/project/backend/calender.py index 5a707c84..93b24e8c 100644 --- a/project/backend/calender.py +++ b/project/backend/calender.py @@ -1,6 +1,8 @@ """Calendar application for OOP tkinter.""" import tkinter as tk from DBHandler import DBHandler +from pages.addeventpage import AddEventPage +from pages.calendarpage import CalendarPage class Application(tk.Tk): @@ -33,6 +35,8 @@ def create_pages(self): self.pages[AddEventPage] = AddEventPage(self) + self.pages[AddEventPage] = AddEventPage(self) + self.pages[CalendarPage] = CalendarPage(self) self.change_page(CalendarPage) @@ -52,127 +56,6 @@ def change_page(self, new_page): self.pages[new_page].grid(row=0, column=0) -class CalendarPage(tk.Frame): - """Example page for Application.""" - - eventLabels = { - 0: "ID", - 1: "Name", - 2: "Location", - 3: "Date", - 4: "Description" - } - - def __init__(self, parent): - """ - Initialise the Example page. - - Arguments: - None - Returns: - None - """ - super().__init__() - self.parent = parent - self.create_widgets() - - def create_widgets(self): - """ - Create the pages widgets. - - Arguments: - None - Returns: - None - """ - - # Create an add event button - self.addEventBtn = tk.Button(self, - text="[+] Add event", - command=lambda: self.parent.change_page( - AddEventPage - )) - self.addEventBtn.grid() - # Fetch all events - events = self.parent.dbh.fetchEvents() - - # Event format: - # (ID, name, location, description)-- - for event in events: - string = "" - for value in event: - string += self.eventLabels[event.index(value)] + " - " - string += str(value) + "\n" - eventPanel = tk.PanedWindow(self, bd=5, relief="sunken", width=600) - eventPanel.grid() - eventPanel.add(tk.Label(self, text=string)) - - - -class AddEventPage(tk.Frame): - """Page where you can add events to the calendar.""" - - def __init__(self, parent): - """ - Initialise the Add Event page. - - Arguments: - None - Returns: - None - """ - super().__init__() - self.parent = parent - self.create_widgets() - - def create_widgets(self): - """ - Create the pages widgets. - - Arguments: - None - Returns: - None - """ - self.title = tk.Label(self, text="Add an event", font=(30)) - self.title.grid(column=1) - # Name - self.name = tk.Label(self, text="Name", font=(24)) - self.name.grid(row=1, sticky="E") - self.nameEntry = tk.Entry(self) - self.nameEntry.grid(row=1, column=1) - # Location - self.location = tk.Label(self, text="Location", font=(24)) - self.location.grid(row=2, sticky="E") - self.locationEntry = tk.Entry(self) - self.locationEntry.grid(row=2, column=1) - # Date - self.date = tk.Label(self, text="Date", font=(24)) - self.date.grid(row=3, sticky="E") - self.dateEntry = tk.Entry(self) - self.dateEntry.grid(row=3, column=1) - # Description - self.description = tk.Label(self, text="Description", font=(24)) - self.description.grid(row=4, sticky="E") - self.descriptionEntry = tk.Text(self, height=5, width=15) - self.descriptionEntry.grid(row=4, column=1) - # Submit Button - if len(self.nameEntry.get()) == 0 or \ - len(self.locationEntry.get()) == 0 or \ - len(self.dateEntry.get()) == 0 or \ - len(self.descriptionEntry.get("1.0")) == 0: - # Need some sort of UI goodness here! - print("[AddEventPage] Not all boxes filled") - self.submitBtn = tk.Button(self, - text="Submit ✔", - command=lambda: self.parent.dbh.addEvent( - self.nameEntry.get(), - self.locationEntry.get(), - self.dateEntry.get(), - self.descriptionEntry.get("1.0") - )) - self.submitBtn.grid() - if __name__ == "__main__": app = Application() app.mainloop() diff --git a/project/backend/pages/addeventpage.py b/project/backend/pages/addeventpage.py new file mode 100644 index 00000000..2e6e4dfa --- /dev/null +++ b/project/backend/pages/addeventpage.py @@ -0,0 +1,68 @@ +"""Add event page for the calendar application.""" +import tkinter as tk + + +class AddEventPage(tk.Frame): + """Page where you can add events to the calendar.""" + + def __init__(self, parent): + """ + Initialise the Add Event page. + + Arguments: + None + Returns: + None + """ + super().__init__() + self.parent = parent + self.create_widgets() + + def create_widgets(self): + """ + Create the pages widgets. + + Arguments: + None + Returns: + None + """ + self.title = tk.Label(self, text="Add an event", font=(30)) + self.title.grid(column=1) + # Name + self.name = tk.Label(self, text="Name", font=(24)) + self.name.grid(row=1, sticky="E") + self.nameEntry = tk.Entry(self) + self.nameEntry.grid(row=1, column=1) + # Location + self.location = tk.Label(self, text="Location", font=(24)) + self.location.grid(row=2, sticky="E") + self.locationEntry = tk.Entry(self) + self.locationEntry.grid(row=2, column=1) + # Date + self.date = tk.Label(self, text="Date", font=(24)) + self.date.grid(row=3, sticky="E") + self.dateEntry = tk.Entry(self) + self.dateEntry.grid(row=3, column=1) + # Description + self.description = tk.Label(self, text="Description", font=(24)) + self.description.grid(row=4, sticky="E") + self.descriptionEntry = tk.Text(self, height=5, width=15) + self.descriptionEntry.grid(row=4, column=1) + # Submit Button + if len(self.nameEntry.get()) == 0 or \ + len(self.locationEntry.get()) == 0 or \ + len(self.dateEntry.get()) == 0 or \ + len(self.descriptionEntry.get("1.0")) == 0: + # Need some sort of UI goodness here! + print("[AddEventPage] Not all boxes filled") + # Break out + self.submitBtn = tk.Button(self, + text="Submit ✔", + command=lambda: self.parent.dbh.addEvent( + self.nameEntry.get(), + self.locationEntry.get(), + self.dateEntry.get(), + self.descriptionEntry.get("1.0") + )) + self.submitBtn.grid() diff --git a/project/backend/pages/calendarpage.py b/project/backend/pages/calendarpage.py new file mode 100644 index 00000000..4d57a4b0 --- /dev/null +++ b/project/backend/pages/calendarpage.py @@ -0,0 +1,57 @@ +"""Main page for the calendar application.""" +import tkinter as tk +from pages.addeventpage import AddEventPage + + +class CalendarPage(tk.Frame): + """Example page for Application.""" + + eventLabels = { + 0: "ID", + 1: "Name", + 2: "Location", + 3: "Date", + 4: "Description" + } + + def __init__(self, parent): + """ + Initialise the Example page. + + Arguments: + None + Returns: + None + """ + super().__init__() + self.parent = parent + self.create_widgets() + + def create_widgets(self): + """ + Create the pages widgets. + + Arguments: + None + Returns: + None + """ + # Create an add event button + self.addEventBtn = tk.Button(self, + text="[+] Add event", + command=lambda: self.parent.change_page( + AddEventPage + )) + self.addEventBtn.grid() + # Fetch all events + events = self.parent.dbh.fetchEvents() + # Event format: + # (ID, name, location, description)-- + for event in events: + string = "" + for value in event: + string += self.eventLabels[event.index(value)] + " - " + string += str(value) + "\n" + eventPanel = tk.PanedWindow(self, bd=5, relief="sunken", width=600) + eventPanel.grid() + eventPanel.add(tk.Label(self, text=string)) From 62a3ea19cd17e20ba9853414a88e1693bbf6abdf Mon Sep 17 00:00:00 2001 From: Zomatree Date: Sun, 24 Feb 2019 22:53:17 +0000 Subject: [PATCH 13/41] made the basic translation file with a simple one way translation function --- project/backend/translator.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 project/backend/translator.py diff --git a/project/backend/translator.py b/project/backend/translator.py new file mode 100644 index 00000000..5c9d0098 --- /dev/null +++ b/project/backend/translator.py @@ -0,0 +1,17 @@ +"""The backend of the traslation.""" +from googletrans import Translator + +translator = Translator() + + +def translate(inp, lang: str): + """ + Translates text from english to another language. + + Parameters: + - list/string - a text you want to translate + - string - the language you want to translate into + Returns: + - string - the translated text. + """ + return translator.translate(inp, dest=lang).text From c367d1bfcb705f790e695c67c13f90ae842e7931 Mon Sep 17 00:00:00 2001 From: Felix Date: Sun, 24 Feb 2019 22:54:42 +0000 Subject: [PATCH 14/41] File Merging Merged Zrupi UI with main file. Fixed errors with DBHandler addEvent call. --- events.db | Bin 0 -> 8192 bytes project/UI/application.py | 171 +++++++++++++++++++++++++- project/backend/DBHandler.py | 18 ++- project/backend/calender.py | 61 --------- project/backend/pages/addeventpage.py | 68 ---------- project/backend/pages/calendarpage.py | 57 --------- 6 files changed, 177 insertions(+), 198 deletions(-) create mode 100644 events.db delete mode 100644 project/backend/calender.py delete mode 100644 project/backend/pages/addeventpage.py delete mode 100644 project/backend/pages/calendarpage.py diff --git a/events.db b/events.db new file mode 100644 index 0000000000000000000000000000000000000000..95ea946a978bd7f2c8fc969a41c0b50837c55b13 GIT binary patch literal 8192 zcmeI#%}T>S5C`ztP!t4-*hB4YjtWwczJO6z35_33_s|}UA@G){-B!D;-YaLvGm#g`T~&|4WvU~i*+dtK z=KAb-kAFmb#qpidH#+5qG`@|}5%=`ybS*Epb77;0X8mebOsva_{EzFY^*{RGE2mOT z%Ix{O_@w@uFDP7W2R~j30SG_<0uX=z1Rwwb2tWV=5P-n{0*7jcn$1>tpNn}d%u^|H F{R!^cKd=A* literal 0 HcmV?d00001 diff --git a/project/UI/application.py b/project/UI/application.py index 1b99e5fc..aba32c6b 100644 --- a/project/UI/application.py +++ b/project/UI/application.py @@ -1,30 +1,199 @@ +"""Green Greenhouses Calendar Application.""" import tkinter as tk +from ..backend.DBHandler import DBHandler + + class Application(tk.Tk): + """Main Application class inheriting from tkinter.Tk.""" + def __init__(self): + """Initialise Application class.""" super().__init__() + self.dbh = DBHandler() + self.pages = {} self.create_pages() def create_pages(self): + """ + Create the applications pages. + + Arguments: + N/A + Returns: + N/A + """ self.pages[HomePage] = HomePage(self) + self.pages[AddEventPage] = AddEventPage(self) + self.pages[CalendarPage] = CalendarPage(self) self.change_page(HomePage) def change_page(self, new_page): + """ + Change the currently displayed page. + + Arguments: + new_page - The page to change to + Returns: + N/A + """ for page in self.grid_slaves(): page.grid_remove() self.pages[new_page].grid(column=0, row=0) + class HomePage(tk.Frame): + """Landing page for application.""" + def __init__(self, parent): + """Initialise Home Page class.""" super().__init__(parent) + self.parent = parent + self.create_widgets() def create_widgets(self): + """ + Create the pages widgets. + + Arguments: + N/A + Returns: + N/A + """ self.title = tk.Label(self, text="Hello World") - self.title.pack() + self.title.grid(row=0, column=0) + + self.button = tk.Button(self, text="Go to add event", + command=lambda: self.parent.change_page(CalendarPage)) + self.button.grid(row=1, column=0) + + +class AddEventPage(tk.Frame): + """Page where you can add events to the calendar.""" + + def __init__(self, parent): + """ + Initialise the Add Event page. + + Arguments: + None + Returns: + None + """ + super().__init__() + + self.parent = parent + + self.create_widgets() + + def create_widgets(self): + """ + Create the pages widgets. + + Arguments: + N/A + Returns: + N/A + """ + self.title = tk.Label(self, text="Add an event", font=(30)) + self.title.grid(column=1) + # Name + self.name = tk.Label(self, text="Name", font=(24)) + self.name.grid(row=1, sticky="E") + self.nameEntry = tk.Entry(self) + self.nameEntry.grid(row=1, column=1) + # Location + self.location = tk.Label(self, text="Location", font=(24)) + self.location.grid(row=2, sticky="E") + self.locationEntry = tk.Entry(self) + self.locationEntry.grid(row=2, column=1) + # Date + self.date = tk.Label(self, text="Date", font=(24)) + self.date.grid(row=3, sticky="E") + self.dateEntry = tk.Entry(self) + self.dateEntry.grid(row=3, column=1) + # Description + self.description = tk.Label(self, text="Description", font=(24)) + self.description.grid(row=4, sticky="E") + self.descriptionEntry = tk.Text(self, height=5, width=15) + self.descriptionEntry.grid(row=4, column=1) + # Submit Button + if len(self.nameEntry.get()) == 0 or \ + len(self.locationEntry.get()) == 0 or \ + len(self.dateEntry.get()) == 0 or \ + len(self.descriptionEntry.get("1.0")) == 0: + # Need some sort of UI goodness here! + print("[AddEventPage] Not all boxes filled") + # Break out + self.submitBtn = tk.Button( + self, + text="Submit ✔", + command=lambda: self.parent.dbh.addEvent( + self.nameEntry.get(), + self.locationEntry.get(), + self.dateEntry.get(), + self.descriptionEntry.get("1.0"))) + + self.submitBtn.grid() + + +class CalendarPage(tk.Frame): + """Example page for Application.""" + + eventLabels = { + 0: "ID", + 1: "Name", + 2: "Location", + 3: "Date", + 4: "Description" + } + + def __init__(self, parent): + """ + Initialise the Example page. + + Arguments: + None + Returns: + None + """ + super().__init__() + + self.parent = parent + + self.create_widgets() + + def create_widgets(self): + """ + Create the pages widgets. + + Arguments: + None + Returns: + None + """ + # Create an add event button + self.addEventBtn = tk.Button(self, + text="[+] Add event", + command=lambda: self.parent.change_page( + AddEventPage)) + self.addEventBtn.grid() + # Fetch all events + events = self.parent.dbh.fetchEvents() + # Event format: + # (ID, name, location, description)-- + for event in events: + string = "" + for value in event: + string += self.eventLabels[event.index(value)] + " - " + string += str(value) + "\n" + eventPanel = tk.PanedWindow(self, bd=5, relief="sunken", width=600) + eventPanel.grid() + eventPanel.add(tk.Label(self, text=string)) diff --git a/project/backend/DBHandler.py b/project/backend/DBHandler.py index 3e7d3445..a1db768c 100644 --- a/project/backend/DBHandler.py +++ b/project/backend/DBHandler.py @@ -22,9 +22,8 @@ def __init__(self): location TEXT, date TEXT, description TEXT)""") - - # self.populate() + # self.populate() def fetchEvents(self): """Fetch event from the database.""" @@ -35,16 +34,13 @@ def fetchEvents(self): def addEvent(self, name, location, date, description): """Create a new event and add it to the database.""" - - self.cursor.execute('''INSERT INTO users(name,location, + self.cursor.execute('''INSERT INTO events(name,location, date,description) - VALUES(?,?,?)''', (name, - location, - date, - description - ) - ) - self.db.commit() + VALUES(?,?,?,?)''', (name, + location, + date, + description)) + self.conn.commit() # TESTING - ONLY USED IN DEVELOPMENT. REMOVE UPON RELEASE!!! def populate(self): diff --git a/project/backend/calender.py b/project/backend/calender.py deleted file mode 100644 index 93b24e8c..00000000 --- a/project/backend/calender.py +++ /dev/null @@ -1,61 +0,0 @@ -"""Calendar application for OOP tkinter.""" -import tkinter as tk -from DBHandler import DBHandler -from pages.addeventpage import AddEventPage -from pages.calendarpage import CalendarPage - - -class Application(tk.Tk): - """Application class inheriting from tk.Tk.""" - - def __init__(self): - """ - Initialise the Application class. - - Arguments: - None - Returns: - None - """ - self.dbh = DBHandler() - super().__init__() - - self.create_pages() - - def create_pages(self): - """ - Create the pages used inside the application. - - Arguments: - None - Returns: - None - """ - self.pages = {} - - self.pages[AddEventPage] = AddEventPage(self) - - self.pages[AddEventPage] = AddEventPage(self) - - self.pages[CalendarPage] = CalendarPage(self) - - self.change_page(CalendarPage) - - def change_page(self, new_page): - """ - Change the currently displayed page. - - Arguments: - newFrame -- The frame to change to - """ - # Remove anything currently placed on the screen - for page in self.grid_slaves(): - if page.grid_info()["column"] == 0: - page.grid_forget() - # Place our new page onto the screen - self.pages[new_page].grid(row=0, column=0) - - -if __name__ == "__main__": - app = Application() - app.mainloop() diff --git a/project/backend/pages/addeventpage.py b/project/backend/pages/addeventpage.py deleted file mode 100644 index 2e6e4dfa..00000000 --- a/project/backend/pages/addeventpage.py +++ /dev/null @@ -1,68 +0,0 @@ -"""Add event page for the calendar application.""" -import tkinter as tk - - -class AddEventPage(tk.Frame): - """Page where you can add events to the calendar.""" - - def __init__(self, parent): - """ - Initialise the Add Event page. - - Arguments: - None - Returns: - None - """ - super().__init__() - self.parent = parent - self.create_widgets() - - def create_widgets(self): - """ - Create the pages widgets. - - Arguments: - None - Returns: - None - """ - self.title = tk.Label(self, text="Add an event", font=(30)) - self.title.grid(column=1) - # Name - self.name = tk.Label(self, text="Name", font=(24)) - self.name.grid(row=1, sticky="E") - self.nameEntry = tk.Entry(self) - self.nameEntry.grid(row=1, column=1) - # Location - self.location = tk.Label(self, text="Location", font=(24)) - self.location.grid(row=2, sticky="E") - self.locationEntry = tk.Entry(self) - self.locationEntry.grid(row=2, column=1) - # Date - self.date = tk.Label(self, text="Date", font=(24)) - self.date.grid(row=3, sticky="E") - self.dateEntry = tk.Entry(self) - self.dateEntry.grid(row=3, column=1) - # Description - self.description = tk.Label(self, text="Description", font=(24)) - self.description.grid(row=4, sticky="E") - self.descriptionEntry = tk.Text(self, height=5, width=15) - self.descriptionEntry.grid(row=4, column=1) - # Submit Button - if len(self.nameEntry.get()) == 0 or \ - len(self.locationEntry.get()) == 0 or \ - len(self.dateEntry.get()) == 0 or \ - len(self.descriptionEntry.get("1.0")) == 0: - # Need some sort of UI goodness here! - print("[AddEventPage] Not all boxes filled") - # Break out - self.submitBtn = tk.Button(self, - text="Submit ✔", - command=lambda: self.parent.dbh.addEvent( - self.nameEntry.get(), - self.locationEntry.get(), - self.dateEntry.get(), - self.descriptionEntry.get("1.0") - )) - self.submitBtn.grid() diff --git a/project/backend/pages/calendarpage.py b/project/backend/pages/calendarpage.py deleted file mode 100644 index 4d57a4b0..00000000 --- a/project/backend/pages/calendarpage.py +++ /dev/null @@ -1,57 +0,0 @@ -"""Main page for the calendar application.""" -import tkinter as tk -from pages.addeventpage import AddEventPage - - -class CalendarPage(tk.Frame): - """Example page for Application.""" - - eventLabels = { - 0: "ID", - 1: "Name", - 2: "Location", - 3: "Date", - 4: "Description" - } - - def __init__(self, parent): - """ - Initialise the Example page. - - Arguments: - None - Returns: - None - """ - super().__init__() - self.parent = parent - self.create_widgets() - - def create_widgets(self): - """ - Create the pages widgets. - - Arguments: - None - Returns: - None - """ - # Create an add event button - self.addEventBtn = tk.Button(self, - text="[+] Add event", - command=lambda: self.parent.change_page( - AddEventPage - )) - self.addEventBtn.grid() - # Fetch all events - events = self.parent.dbh.fetchEvents() - # Event format: - # (ID, name, location, description)-- - for event in events: - string = "" - for value in event: - string += self.eventLabels[event.index(value)] + " - " - string += str(value) + "\n" - eventPanel = tk.PanedWindow(self, bd=5, relief="sunken", width=600) - eventPanel.grid() - eventPanel.add(tk.Label(self, text=string)) From 605e4754d3823c66e66ad7ea7089a2bfb7a677b1 Mon Sep 17 00:00:00 2001 From: Owen Throup <38217027+Throupy@users.noreply.github.com> Date: Mon, 25 Feb 2019 18:55:28 +0000 Subject: [PATCH 15/41] Update DBHandler.py Moved some brackets. --- project/backend/DBHandler.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/project/backend/DBHandler.py b/project/backend/DBHandler.py index 0043c100..b7633307 100644 --- a/project/backend/DBHandler.py +++ b/project/backend/DBHandler.py @@ -22,9 +22,8 @@ def __init__(self): location TEXT, date TEXT, description TEXT)""") - - # self.populate() + # self.populate() def fetchEvents(self): """Fetch event from the database.""" @@ -55,4 +54,6 @@ def populate(self): "Office on 4th street", """Talk about upcoming work events""", + ) + ) self.conn.commit() From 1e33312288cd54994010b70367008c1f27c80e77 Mon Sep 17 00:00:00 2001 From: Owen Throup <38217027+Throupy@users.noreply.github.com> Date: Mon, 25 Feb 2019 19:06:05 +0000 Subject: [PATCH 16/41] Remove Event -> Added a method to remove an event from the database - functional but needs to be hooked up to the UI which I hope is a WIP. -> Fixed some PEP-8 Gucciness. --- project/backend/DBHandler.py | 30 ++++++++++++++++++++++++++++-- project/backend/calender.py | 2 +- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/project/backend/DBHandler.py b/project/backend/DBHandler.py index 2f42065f..54c60bae 100644 --- a/project/backend/DBHandler.py +++ b/project/backend/DBHandler.py @@ -26,15 +26,29 @@ def __init__(self): # self.populate() def fetchEvents(self): - """Fetch event from the database.""" + """Fetch event from the database. + + Arguments: + None + Returns: + None + """ self.cursor.execute("""SELECT * FROM events""") # Fetch rows rows = self.cursor.fetchall() return rows def addEvent(self, name, location, date, description): - """Create a new event and add it to the database.""" + """Create a new event and add it to the database. + Arguments: + name - name of event + location - location of event + date - date of event + description - description of event + Returns: + None + """ self.cursor.execute('''INSERT INTO users(name,location, date,description) VALUES(?,?,?)''', (name, @@ -45,6 +59,18 @@ def addEvent(self, name, location, date, description): ) self.db.commit() + def removeEvent(self, id): + """Remove an event from the database. + + Arguments: + ID - The ID of the event that is to be removed + Returns: + None + """ + # Remove the event with the specified ID + self.cursor.execute("DELETE FROM events WHERE id = ?", (id,)) + self.conn.commit() + # TESTING - ONLY USED IN DEVELOPMENT. REMOVE UPON RELEASE!!! def populate(self): """Use to populate the database with sample data.""" diff --git a/project/backend/calender.py b/project/backend/calender.py index 93b24e8c..42828ba9 100644 --- a/project/backend/calender.py +++ b/project/backend/calender.py @@ -32,7 +32,7 @@ def create_pages(self): None """ self.pages = {} - + self.pages[AddEventPage] = AddEventPage(self) self.pages[AddEventPage] = AddEventPage(self) From 4f3046f385ca8100fa319481378385b3252c2e9e Mon Sep 17 00:00:00 2001 From: Owen Throup <38217027+Throupy@users.noreply.github.com> Date: Mon, 25 Feb 2019 20:03:53 +0000 Subject: [PATCH 17/41] Delete Button and PEP-8 -> Hooked up delete functionality to basic button and UI - It doesn't refresh, see discord. -> Fixed some PEP-8 violations -> Fixed wrong table name --- project/backend/DBHandler.py | 6 ++++-- project/backend/events.db | Bin 8192 -> 8192 bytes project/backend/pages/addeventpage.py | 13 +++++++------ project/backend/pages/calendarpage.py | 19 ++++++++++++++++--- 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/project/backend/DBHandler.py b/project/backend/DBHandler.py index 54c60bae..dd538a22 100644 --- a/project/backend/DBHandler.py +++ b/project/backend/DBHandler.py @@ -49,7 +49,7 @@ def addEvent(self, name, location, date, description): Returns: None """ - self.cursor.execute('''INSERT INTO users(name,location, + self.cursor.execute('''INSERT INTO events(name,location, date,description) VALUES(?,?,?)''', (name, location, @@ -69,6 +69,7 @@ def removeEvent(self, id): """ # Remove the event with the specified ID self.cursor.execute("DELETE FROM events WHERE id = ?", (id,)) + print(f"Deleted event with ID: {id}") self.conn.commit() # TESTING - ONLY USED IN DEVELOPMENT. REMOVE UPON RELEASE!!! @@ -80,5 +81,6 @@ def populate(self): VALUES(?,?,?,?)""", ("Meeting", "Office on 4th street", """Talk about upcoming - work events""",)) + work events""", + "12/02")) self.conn.commit() diff --git a/project/backend/events.db b/project/backend/events.db index 7b774c0faaad34fd4ba1fb6386cc21b835f081a4..74c0f514473f707e60870c21834322af75ecb552 100644 GIT binary patch literal 8192 zcmeH~%}&BV5XW~B#V8-%kjP=YX=0=ni6;{gH>Lu9)E?xxltmk$CGDaI;sKw@lMi4# z_(YyugBSy-$A&o5-L|tkn`wWW+2ntDQE{YzrssFKggjXxl#&AgLP%Eii0UJw>LogI z)bqpt%d%v9^(CRAXljS3hK2-?01`j~NB{{S0VIF~kN^@u0!Uys2n;GTmd<48Lm+v* zEyS&GWiY%)N+v5>46Nc|g~4!aV+qF0I0EC;V#mycbJM66%^H+hZEGUV0xQ6lqkgQOmlPs#oGbKDqS%dfMs9r%?<00|%g zB!C2v01`j~NZ=n6xL+%z2ZgE-(s8fPnoY+Rpmf5nyn#UaYIsM_X}ZPRE#P&pC!yE1 zy^e~VkRM~JWx9Lk`K?c((_f5{@RG+uOrF{!Z=wCUN*>~#M?=Kkp9?X$I%2}ZenJ;i XsjZiPDRV8KQ%%=&ZAz`fx3YZ)ASF-? delta 57 zcmZp0XmFSy&B#1a#+i|MW5PmyZUzPhCjJZt{w@3&8w(HcO>CIM;l;$pAZ@DXJ=sBC Ndh&I7&B Date: Mon, 25 Feb 2019 20:49:49 +0000 Subject: [PATCH 18/41] Updated Event Viewer --- events.db | Bin 8192 -> 8192 bytes project/UI/application.py | 16 ++++++------ project/UI/eventViewer.py | 50 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 8 deletions(-) create mode 100644 project/UI/eventViewer.py diff --git a/events.db b/events.db index 95ea946a978bd7f2c8fc969a41c0b50837c55b13..daf0fde0716454f829e29fba0aa93dd3d444d8a2 100644 GIT binary patch delta 190 zcmZp0XmFSy&B!@X#+i|GW5N=C5f1)*2L3nv=lECi&*z`a-_BpnpTAj9Ae_IRi-V1U z9|+QcfQuc8&4$EgMPjoc*ow?-4C1Qt`~i+dC6&dAnfWOhrI}@k#VHwyWyL93d0E+6 zGE6`vva7WPi&YXBE-nXAS^7-@1K_%Ql1}@ JQIwkM1^|m;4%`3$ diff --git a/project/UI/application.py b/project/UI/application.py index aba32c6b..33f0f6e8 100644 --- a/project/UI/application.py +++ b/project/UI/application.py @@ -3,6 +3,8 @@ from ..backend.DBHandler import DBHandler +from .eventViewer import EventViewer + class Application(tk.Tk): """Main Application class inheriting from tkinter.Tk.""" @@ -188,12 +190,10 @@ def create_widgets(self): # Fetch all events events = self.parent.dbh.fetchEvents() # Event format: - # (ID, name, location, description)-- + # (ID, name, location, Date, description)-- + self.grid_columnconfigure(0, weight=1) + + self.event_viewer = EventViewer(self) + self.event_viewer.grid(row=10, column=0) for event in events: - string = "" - for value in event: - string += self.eventLabels[event.index(value)] + " - " - string += str(value) + "\n" - eventPanel = tk.PanedWindow(self, bd=5, relief="sunken", width=600) - eventPanel.grid() - eventPanel.add(tk.Label(self, text=string)) + self.event_viewer.add_event(event) diff --git a/project/UI/eventViewer.py b/project/UI/eventViewer.py new file mode 100644 index 00000000..b969f817 --- /dev/null +++ b/project/UI/eventViewer.py @@ -0,0 +1,50 @@ +"""Event viewer specific class.""" +import tkinter as tk + + +class EventViewer(tk.Frame): + """Shows all event information in a single frame.""" + + eventLabels = { + 0: "ID", + 1: "Name", + 2: "Location", + 3: "Date", + 4: "Description" + } + + def __init__(self, parent): + """Initialise the Event Viewer class.""" + super().__init__(parent) + + self.canvas = tk.Canvas(self) + self.display_frame = tk.Frame(self.canvas) + self.scrollbar = tk.Scrollbar(self, orient="vertical", + command=self.canvas.yview) + self.canvas.configure(yscrollcommand=self.scrollbar.set) + + self.scrollbar.pack(side="right", fill="y") + self.canvas.pack(side="left", padx=10) + self.canvas.create_window((0, 0), window=self.display_frame, anchor="nw") + + self.display_frame.bind("", self.scrollMove) + self.events = {} + + def scrollMove(self, event): + """Update canvas information from scrollbar movement.""" + self.canvas.configure(scrollregion=self.canvas.bbox("all"), + width=300, height=500) + + def add_event(self, event): + """Add a new event to the viewer.""" + self.widgets = {} + + event_frame = tk.Frame(self.display_frame, height=200, width=300, + relief=tk.GROOVE, borderwidth=3) + event_frame.pack(fill="both", expand=True) + + self.events.update({event: event_frame}) + + for key, name in self.eventLabels.items(): + widget = tk.Label(event_frame, text=name+" - "+str(event[key])) + widget.pack() From 6f21c7ca6f9052f75289da1d8c9f1a4016618c2c Mon Sep 17 00:00:00 2001 From: FelixR Date: Mon, 25 Feb 2019 20:57:03 +0000 Subject: [PATCH 19/41] Updated Event Viewer (#5) --- events.db | Bin 8192 -> 8192 bytes project/UI/application.py | 16 ++++++------ project/UI/eventViewer.py | 50 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 8 deletions(-) create mode 100644 project/UI/eventViewer.py diff --git a/events.db b/events.db index 95ea946a978bd7f2c8fc969a41c0b50837c55b13..daf0fde0716454f829e29fba0aa93dd3d444d8a2 100644 GIT binary patch delta 190 zcmZp0XmFSy&B!@X#+i|GW5N=C5f1)*2L3nv=lECi&*z`a-_BpnpTAj9Ae_IRi-V1U z9|+QcfQuc8&4$EgMPjoc*ow?-4C1Qt`~i+dC6&dAnfWOhrI}@k#VHwyWyL93d0E+6 zGE6`vva7WPi&YXBE-nXAS^7-@1K_%Ql1}@ JQIwkM1^|m;4%`3$ diff --git a/project/UI/application.py b/project/UI/application.py index aba32c6b..33f0f6e8 100644 --- a/project/UI/application.py +++ b/project/UI/application.py @@ -3,6 +3,8 @@ from ..backend.DBHandler import DBHandler +from .eventViewer import EventViewer + class Application(tk.Tk): """Main Application class inheriting from tkinter.Tk.""" @@ -188,12 +190,10 @@ def create_widgets(self): # Fetch all events events = self.parent.dbh.fetchEvents() # Event format: - # (ID, name, location, description)-- + # (ID, name, location, Date, description)-- + self.grid_columnconfigure(0, weight=1) + + self.event_viewer = EventViewer(self) + self.event_viewer.grid(row=10, column=0) for event in events: - string = "" - for value in event: - string += self.eventLabels[event.index(value)] + " - " - string += str(value) + "\n" - eventPanel = tk.PanedWindow(self, bd=5, relief="sunken", width=600) - eventPanel.grid() - eventPanel.add(tk.Label(self, text=string)) + self.event_viewer.add_event(event) diff --git a/project/UI/eventViewer.py b/project/UI/eventViewer.py new file mode 100644 index 00000000..b969f817 --- /dev/null +++ b/project/UI/eventViewer.py @@ -0,0 +1,50 @@ +"""Event viewer specific class.""" +import tkinter as tk + + +class EventViewer(tk.Frame): + """Shows all event information in a single frame.""" + + eventLabels = { + 0: "ID", + 1: "Name", + 2: "Location", + 3: "Date", + 4: "Description" + } + + def __init__(self, parent): + """Initialise the Event Viewer class.""" + super().__init__(parent) + + self.canvas = tk.Canvas(self) + self.display_frame = tk.Frame(self.canvas) + self.scrollbar = tk.Scrollbar(self, orient="vertical", + command=self.canvas.yview) + self.canvas.configure(yscrollcommand=self.scrollbar.set) + + self.scrollbar.pack(side="right", fill="y") + self.canvas.pack(side="left", padx=10) + self.canvas.create_window((0, 0), window=self.display_frame, anchor="nw") + + self.display_frame.bind("", self.scrollMove) + self.events = {} + + def scrollMove(self, event): + """Update canvas information from scrollbar movement.""" + self.canvas.configure(scrollregion=self.canvas.bbox("all"), + width=300, height=500) + + def add_event(self, event): + """Add a new event to the viewer.""" + self.widgets = {} + + event_frame = tk.Frame(self.display_frame, height=200, width=300, + relief=tk.GROOVE, borderwidth=3) + event_frame.pack(fill="both", expand=True) + + self.events.update({event: event_frame}) + + for key, name in self.eventLabels.items(): + widget = tk.Label(event_frame, text=name+" - "+str(event[key])) + widget.pack() From 7c921085b2e349a6f35dfeeb7d6234865460a202 Mon Sep 17 00:00:00 2001 From: zomatree <39768508+zomatree@users.noreply.github.com> Date: Mon, 25 Feb 2019 22:02:49 +0000 Subject: [PATCH 20/41] added date checking using regex and added a InputCheck function to check if all inputs have been filled --- application.py | 232 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 232 insertions(+) create mode 100644 application.py diff --git a/application.py b/application.py new file mode 100644 index 00000000..731fb510 --- /dev/null +++ b/application.py @@ -0,0 +1,232 @@ +"""Green Greenhouses Calendar Application.""" +import tkinter as tk +from tkinter import messagebox +import re +from ..backend.DBHandler import DBHandler + +from .eventViewer import EventViewer + + +class Application(tk.Tk): + """Main Application class inheriting from tkinter.Tk.""" + + def __init__(self): + """Initialise Application class.""" + super().__init__() + + self.dbh = DBHandler() + + self.pages = {} + + self.create_pages() + + def create_pages(self): + """ + Create the applications pages. + + Arguments: + N/A + Returns: + N/A + """ + self.pages[HomePage] = HomePage(self) + self.pages[AddEventPage] = AddEventPage(self) + self.pages[CalendarPage] = CalendarPage(self) + + self.change_page(HomePage) + + def change_page(self, new_page): + """ + Change the currently displayed page. + + Arguments: + new_page - The page to change to + Returns: + N/A + """ + for page in self.grid_slaves(): + page.grid_remove() + + self.pages[new_page].grid(column=0, row=0) + + +class HomePage(tk.Frame): + """Landing page for application.""" + + def __init__(self, parent): + """Initialise Home Page class.""" + super().__init__(parent) + + self.parent = parent + + self.create_widgets() + + def create_widgets(self): + """ + Create the pages widgets. + + Arguments: + N/A + Returns: + N/A + """ + self.title = tk.Label(self, text="Hello World") + self.title.grid(row=0, column=0) + + self.button = tk.Button(self, text="Go to add event", + command=lambda: + self.parent.change_page(CalendarPage)) + self.button.grid(row=1, column=0) + + +class AddEventPage(tk.Frame): + """Page where you can add events to the calendar.""" + + def __init__(self, parent): + """ + Initialise the Add Event page. + + Arguments: + None + Returns: + None + """ + super().__init__() + + self.parent = parent + + self.create_widgets() + + def create_widgets(self): + """ + Create the pages widgets. + + Arguments: + N/A + Returns: + N/A + """ + self.title = tk.Label(self, text="Add an event", font=(30)) + self.title.grid(column=1) + # Name + self.name = tk.Label(self, text="Name", font=(24)) + self.name.grid(row=1, sticky="E") + self.nameEntry = tk.Entry(self) + self.nameEntry.grid(row=1, column=1) + # Location + self.location = tk.Label(self, text="Location", font=(24)) + self.location.grid(row=2, sticky="E") + self.locationEntry = tk.Entry(self) + self.locationEntry.grid(row=2, column=1) + # Date + self.date = tk.Label(self, text="Date", font=(24)) + self.date.grid(row=3, sticky="E") + self.dateSpinBoxs = tk.Frame(self) + self.timeEntryD = tk.Spinbox(self.dateSpinBoxs, width=4, to=31) + self.timeEntryM = tk.Spinbox(self.dateSpinBoxs, width=4, to=12) + self.timeEntryY = tk.Spinbox( + self.dateSpinBoxs, + width=4, + from_=2019, + to=3000) + self.timeEntryD.grid(row=3, column=1) + self.timeEntryM.grid(row=3, column=2) + self.timeEntryY.grid(row=3, column=3) + self.dateSpinBoxs.grid(row=3, column=1) + # Description + self.description = tk.Label(self, text="Description", font=(24)) + self.description.grid(row=4, sticky="E") + self.descriptionEntry = tk.Entry(self) + self.descriptionEntry.grid(row=4, column=1) + # Submit Button + + self.submitBtn = tk.Button( + self, + text="Submit ✔", + command=lambda: self.inputCheck()) + self.submitBtn.grid() + + def inputCheck(self): + """ + the Function that checks to see if all date boxs + have been filled out correctly. + + Argumnets: + None + Returns: + None + """ + pattern = re.compile( + r"^\s*(3[01]|[12][0-9]|0?[1-9])\.(1[012]|0?[1-9])\.((?:19|20)\d{2})\s*$") + dateString = f"{self.timeEntryD.get()}.{self.timeEntryM.get().zfill(2)}.{self.timeEntryY.get()}" + date = pattern.match(dateString) + print(self.nameEntry.get()) + print(self.locationEntry.get()) + print(date) + print(self.descriptionEntry.get()) + if (self.nameEntry.get() and + self.locationEntry.get() and + date and self.descriptionEntry.get()): + self.parent.dbh.addEvent( + self.nameEntry.get(), + self.locationEntry.get(), + dateString, + self.descriptionEntry.get()) + else: + messagebox.showinfo( + "Missing arguments", + "It seems you didnt fill out all the info boxs \n" + + "please fill them all and try again.") + + +class CalendarPage(tk.Frame): + """Example page for Application.""" + + eventLabels = { + 0: "ID", + 1: "Name", + 2: "Location", + 3: "Date", + 4: "Description" + } + + def __init__(self, parent): + """ + Initialise the Example page. + + Arguments: + None + Returns: + None + """ + super().__init__() + + self.parent = parent + + self.create_widgets() + + def create_widgets(self): + """ + Create the pages widgets. + + Arguments: + None + Returns: + None + """ + # Create an add event button + self.addEventBtn = tk.Button(self, + text="[+] Add event", + command=lambda: self.parent.change_page( + AddEventPage)) + self.addEventBtn.grid() + # Fetch all events + events = self.parent.dbh.fetchEvents() + # Event format: + # (ID, name, location, Date, description)-- + self.grid_columnconfigure(0, weight=1) + + self.event_viewer = EventViewer(self) + self.event_viewer.grid(row=10, column=0) + for event in events: + self.event_viewer.add_event(event) From 857852fdb47fd4c3dbbb2d78f73194d907761224 Mon Sep 17 00:00:00 2001 From: Felix Date: Mon, 25 Feb 2019 22:58:37 +0000 Subject: [PATCH 21/41] Updated eventViewer Gave application constant size. --- Pipfile | 1 + Pipfile.lock | 47 ++++++++++++++++++++++++++++++++++---- events.db | Bin 8192 -> 8192 bytes project/UI/application.py | 3 +++ project/UI/eventViewer.py | 19 +++++++-------- 5 files changed, 56 insertions(+), 14 deletions(-) diff --git a/Pipfile b/Pipfile index 000bac1e..950f516e 100644 --- a/Pipfile +++ b/Pipfile @@ -7,6 +7,7 @@ verify_ssl = true flake8 = "*" [packages] +flake8 = "*" [requires] python_version = "3.7" diff --git a/Pipfile.lock b/Pipfile.lock index 79354a3c..fc3cef26 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "a376db0bd471e38a7080cd854c46349b46922db98afeaf83d17b84923fbe9710" + "sha256": "6e90e4e61e002075aea15d26a0b7253050f5355dd737991fd59d9a7ae9a60f2b" }, "pipfile-spec": 6, "requires": { @@ -15,7 +15,44 @@ } ] }, - "default": {}, + "default": { + "entrypoints": { + "hashes": [ + "sha256:589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19", + "sha256:c70dd71abe5a8c85e55e12c19bd91ccfeec11a6e99044204511f9ed547d48451" + ], + "version": "==0.3" + }, + "flake8": { + "hashes": [ + "sha256:859996073f341f2670741b51ec1e67a01da142831aa1fdc6242dbf88dffbe661", + "sha256:a796a115208f5c03b18f332f7c11729812c8c3ded6c46319c59b53efd3819da8" + ], + "index": "pypi", + "version": "==3.7.7" + }, + "mccabe": { + "hashes": [ + "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", + "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f" + ], + "version": "==0.6.1" + }, + "pycodestyle": { + "hashes": [ + "sha256:95a2219d12372f05704562a14ec30bc76b05a5b297b21a5dfe3f6fac3491ae56", + "sha256:e40a936c9a450ad81df37f549d676d127b1b66000a6c500caa2b085bc0ca976c" + ], + "version": "==2.5.0" + }, + "pyflakes": { + "hashes": [ + "sha256:5e8c00e30c464c99e0b501dc160b13a14af7f27d4dffb529c556e30a159e231d", + "sha256:f277f9ca3e55de669fba45b7393a1449009cff5a37d1af10ebb76c52765269cd" + ], + "version": "==2.1.0" + } + }, "develop": { "entrypoints": { "hashes": [ @@ -26,11 +63,11 @@ }, "flake8": { "hashes": [ - "sha256:6d8c66a65635d46d54de59b027a1dda40abbe2275b3164b634835ac9c13fd048", - "sha256:6eab21c6e34df2c05416faa40d0c59963008fff29b6f0ccfe8fa28152ab3e383" + "sha256:859996073f341f2670741b51ec1e67a01da142831aa1fdc6242dbf88dffbe661", + "sha256:a796a115208f5c03b18f332f7c11729812c8c3ded6c46319c59b53efd3819da8" ], "index": "pypi", - "version": "==3.7.6" + "version": "==3.7.7" }, "mccabe": { "hashes": [ diff --git a/events.db b/events.db index daf0fde0716454f829e29fba0aa93dd3d444d8a2..f035ceee37f8a2a3d092111121585a1d6e45f7ec 100644 GIT binary patch delta 200 zcmZp0XmFSy&B!%T#+i|8W5N=CF;4z;2L3PnFZl29U*JE&zk`1b{{sH>&58oP{PpIX zYz+F=viu<#sS0kHd5Jj+zNx7tnR)3Tf&82lg~WoyqLSRyyb^_ioW$f*LkoQaV|_#O o5H1cj27Vw&1OhI0BsLoon-z)8g2ZNqv88~TnP40sn-ReV040YmtpET3 delta 193 zcmZp0XmFSy&B!@X#+i|GW5N=C5f1)*2L3nv=lECi&*z`a-_BpnpTAjAz>R-mgJ3-u z2O9%F5TpYE7dsN04T;T)#AZRT6`9!>#8u__100J=DvJ{{^HVZPGs_Z-Q!*0Eic_-k zva+*en1D)TW%&aVfl7k&b5qMRQi}|Y^$m>l4b3x!7=_pvgoVZV{qs^o%JV}qic(YE E0I&owCjbBd diff --git a/project/UI/application.py b/project/UI/application.py index 33f0f6e8..d716fcb5 100644 --- a/project/UI/application.py +++ b/project/UI/application.py @@ -13,6 +13,9 @@ def __init__(self): """Initialise Application class.""" super().__init__() + self.resizable(False, False) + self.geometry("500x500") + self.dbh = DBHandler() self.pages = {} diff --git a/project/UI/eventViewer.py b/project/UI/eventViewer.py index b969f817..89cc1431 100644 --- a/project/UI/eventViewer.py +++ b/project/UI/eventViewer.py @@ -19,29 +19,30 @@ def __init__(self, parent): self.canvas = tk.Canvas(self) self.display_frame = tk.Frame(self.canvas) - self.scrollbar = tk.Scrollbar(self, orient="vertical", + self.scrollbar = tk.Scrollbar(self, orient="vertical", width=20, command=self.canvas.yview) self.canvas.configure(yscrollcommand=self.scrollbar.set) - self.scrollbar.pack(side="right", fill="y") - self.canvas.pack(side="left", padx=10) - self.canvas.create_window((0, 0), window=self.display_frame, anchor="nw") + self.grid_rowconfigure(0, weight=100) + self.scrollbar.grid(row=0, column=1, sticky="ns") + self.canvas.grid(row=0, column=0) + self.canvas.create_window((240, 0), window=self.display_frame, anchor="n") self.display_frame.bind("", self.scrollMove) + self.display_frame.grid_columnconfigure(0, weight=1000) + self.events = {} def scrollMove(self, event): """Update canvas information from scrollbar movement.""" self.canvas.configure(scrollregion=self.canvas.bbox("all"), - width=300, height=500) + width=480, height=450) def add_event(self, event): """Add a new event to the viewer.""" - self.widgets = {} - - event_frame = tk.Frame(self.display_frame, height=200, width=300, + event_frame = tk.Frame(self.display_frame, relief=tk.GROOVE, borderwidth=3) - event_frame.pack(fill="both", expand=True) + event_frame.grid(column=0, pady=5, padx=5) self.events.update({event: event_frame}) From 62b5d080abccbaa243a44f4fc25d62978c986046 Mon Sep 17 00:00:00 2001 From: Felix Date: Mon, 25 Feb 2019 23:13:22 +0000 Subject: [PATCH 22/41] Moved application.py --- application.py | 232 -------------------------------------- project/UI/application.py | 204 ++++++++++++++++++++++++++++++++- 2 files changed, 203 insertions(+), 233 deletions(-) delete mode 100644 application.py diff --git a/application.py b/application.py deleted file mode 100644 index 731fb510..00000000 --- a/application.py +++ /dev/null @@ -1,232 +0,0 @@ -"""Green Greenhouses Calendar Application.""" -import tkinter as tk -from tkinter import messagebox -import re -from ..backend.DBHandler import DBHandler - -from .eventViewer import EventViewer - - -class Application(tk.Tk): - """Main Application class inheriting from tkinter.Tk.""" - - def __init__(self): - """Initialise Application class.""" - super().__init__() - - self.dbh = DBHandler() - - self.pages = {} - - self.create_pages() - - def create_pages(self): - """ - Create the applications pages. - - Arguments: - N/A - Returns: - N/A - """ - self.pages[HomePage] = HomePage(self) - self.pages[AddEventPage] = AddEventPage(self) - self.pages[CalendarPage] = CalendarPage(self) - - self.change_page(HomePage) - - def change_page(self, new_page): - """ - Change the currently displayed page. - - Arguments: - new_page - The page to change to - Returns: - N/A - """ - for page in self.grid_slaves(): - page.grid_remove() - - self.pages[new_page].grid(column=0, row=0) - - -class HomePage(tk.Frame): - """Landing page for application.""" - - def __init__(self, parent): - """Initialise Home Page class.""" - super().__init__(parent) - - self.parent = parent - - self.create_widgets() - - def create_widgets(self): - """ - Create the pages widgets. - - Arguments: - N/A - Returns: - N/A - """ - self.title = tk.Label(self, text="Hello World") - self.title.grid(row=0, column=0) - - self.button = tk.Button(self, text="Go to add event", - command=lambda: - self.parent.change_page(CalendarPage)) - self.button.grid(row=1, column=0) - - -class AddEventPage(tk.Frame): - """Page where you can add events to the calendar.""" - - def __init__(self, parent): - """ - Initialise the Add Event page. - - Arguments: - None - Returns: - None - """ - super().__init__() - - self.parent = parent - - self.create_widgets() - - def create_widgets(self): - """ - Create the pages widgets. - - Arguments: - N/A - Returns: - N/A - """ - self.title = tk.Label(self, text="Add an event", font=(30)) - self.title.grid(column=1) - # Name - self.name = tk.Label(self, text="Name", font=(24)) - self.name.grid(row=1, sticky="E") - self.nameEntry = tk.Entry(self) - self.nameEntry.grid(row=1, column=1) - # Location - self.location = tk.Label(self, text="Location", font=(24)) - self.location.grid(row=2, sticky="E") - self.locationEntry = tk.Entry(self) - self.locationEntry.grid(row=2, column=1) - # Date - self.date = tk.Label(self, text="Date", font=(24)) - self.date.grid(row=3, sticky="E") - self.dateSpinBoxs = tk.Frame(self) - self.timeEntryD = tk.Spinbox(self.dateSpinBoxs, width=4, to=31) - self.timeEntryM = tk.Spinbox(self.dateSpinBoxs, width=4, to=12) - self.timeEntryY = tk.Spinbox( - self.dateSpinBoxs, - width=4, - from_=2019, - to=3000) - self.timeEntryD.grid(row=3, column=1) - self.timeEntryM.grid(row=3, column=2) - self.timeEntryY.grid(row=3, column=3) - self.dateSpinBoxs.grid(row=3, column=1) - # Description - self.description = tk.Label(self, text="Description", font=(24)) - self.description.grid(row=4, sticky="E") - self.descriptionEntry = tk.Entry(self) - self.descriptionEntry.grid(row=4, column=1) - # Submit Button - - self.submitBtn = tk.Button( - self, - text="Submit ✔", - command=lambda: self.inputCheck()) - self.submitBtn.grid() - - def inputCheck(self): - """ - the Function that checks to see if all date boxs - have been filled out correctly. - - Argumnets: - None - Returns: - None - """ - pattern = re.compile( - r"^\s*(3[01]|[12][0-9]|0?[1-9])\.(1[012]|0?[1-9])\.((?:19|20)\d{2})\s*$") - dateString = f"{self.timeEntryD.get()}.{self.timeEntryM.get().zfill(2)}.{self.timeEntryY.get()}" - date = pattern.match(dateString) - print(self.nameEntry.get()) - print(self.locationEntry.get()) - print(date) - print(self.descriptionEntry.get()) - if (self.nameEntry.get() and - self.locationEntry.get() and - date and self.descriptionEntry.get()): - self.parent.dbh.addEvent( - self.nameEntry.get(), - self.locationEntry.get(), - dateString, - self.descriptionEntry.get()) - else: - messagebox.showinfo( - "Missing arguments", - "It seems you didnt fill out all the info boxs \n" + - "please fill them all and try again.") - - -class CalendarPage(tk.Frame): - """Example page for Application.""" - - eventLabels = { - 0: "ID", - 1: "Name", - 2: "Location", - 3: "Date", - 4: "Description" - } - - def __init__(self, parent): - """ - Initialise the Example page. - - Arguments: - None - Returns: - None - """ - super().__init__() - - self.parent = parent - - self.create_widgets() - - def create_widgets(self): - """ - Create the pages widgets. - - Arguments: - None - Returns: - None - """ - # Create an add event button - self.addEventBtn = tk.Button(self, - text="[+] Add event", - command=lambda: self.parent.change_page( - AddEventPage)) - self.addEventBtn.grid() - # Fetch all events - events = self.parent.dbh.fetchEvents() - # Event format: - # (ID, name, location, Date, description)-- - self.grid_columnconfigure(0, weight=1) - - self.event_viewer = EventViewer(self) - self.event_viewer.grid(row=10, column=0) - for event in events: - self.event_viewer.add_event(event) diff --git a/project/UI/application.py b/project/UI/application.py index 1b99e5fc..731fb510 100644 --- a/project/UI/application.py +++ b/project/UI/application.py @@ -1,30 +1,232 @@ +"""Green Greenhouses Calendar Application.""" import tkinter as tk +from tkinter import messagebox +import re +from ..backend.DBHandler import DBHandler + +from .eventViewer import EventViewer + class Application(tk.Tk): + """Main Application class inheriting from tkinter.Tk.""" + def __init__(self): + """Initialise Application class.""" super().__init__() + self.dbh = DBHandler() + self.pages = {} self.create_pages() def create_pages(self): + """ + Create the applications pages. + + Arguments: + N/A + Returns: + N/A + """ self.pages[HomePage] = HomePage(self) + self.pages[AddEventPage] = AddEventPage(self) + self.pages[CalendarPage] = CalendarPage(self) self.change_page(HomePage) def change_page(self, new_page): + """ + Change the currently displayed page. + + Arguments: + new_page - The page to change to + Returns: + N/A + """ for page in self.grid_slaves(): page.grid_remove() self.pages[new_page].grid(column=0, row=0) + class HomePage(tk.Frame): + """Landing page for application.""" + def __init__(self, parent): + """Initialise Home Page class.""" super().__init__(parent) + self.parent = parent + self.create_widgets() def create_widgets(self): + """ + Create the pages widgets. + + Arguments: + N/A + Returns: + N/A + """ self.title = tk.Label(self, text="Hello World") - self.title.pack() + self.title.grid(row=0, column=0) + + self.button = tk.Button(self, text="Go to add event", + command=lambda: + self.parent.change_page(CalendarPage)) + self.button.grid(row=1, column=0) + + +class AddEventPage(tk.Frame): + """Page where you can add events to the calendar.""" + + def __init__(self, parent): + """ + Initialise the Add Event page. + + Arguments: + None + Returns: + None + """ + super().__init__() + + self.parent = parent + + self.create_widgets() + + def create_widgets(self): + """ + Create the pages widgets. + + Arguments: + N/A + Returns: + N/A + """ + self.title = tk.Label(self, text="Add an event", font=(30)) + self.title.grid(column=1) + # Name + self.name = tk.Label(self, text="Name", font=(24)) + self.name.grid(row=1, sticky="E") + self.nameEntry = tk.Entry(self) + self.nameEntry.grid(row=1, column=1) + # Location + self.location = tk.Label(self, text="Location", font=(24)) + self.location.grid(row=2, sticky="E") + self.locationEntry = tk.Entry(self) + self.locationEntry.grid(row=2, column=1) + # Date + self.date = tk.Label(self, text="Date", font=(24)) + self.date.grid(row=3, sticky="E") + self.dateSpinBoxs = tk.Frame(self) + self.timeEntryD = tk.Spinbox(self.dateSpinBoxs, width=4, to=31) + self.timeEntryM = tk.Spinbox(self.dateSpinBoxs, width=4, to=12) + self.timeEntryY = tk.Spinbox( + self.dateSpinBoxs, + width=4, + from_=2019, + to=3000) + self.timeEntryD.grid(row=3, column=1) + self.timeEntryM.grid(row=3, column=2) + self.timeEntryY.grid(row=3, column=3) + self.dateSpinBoxs.grid(row=3, column=1) + # Description + self.description = tk.Label(self, text="Description", font=(24)) + self.description.grid(row=4, sticky="E") + self.descriptionEntry = tk.Entry(self) + self.descriptionEntry.grid(row=4, column=1) + # Submit Button + + self.submitBtn = tk.Button( + self, + text="Submit ✔", + command=lambda: self.inputCheck()) + self.submitBtn.grid() + + def inputCheck(self): + """ + the Function that checks to see if all date boxs + have been filled out correctly. + + Argumnets: + None + Returns: + None + """ + pattern = re.compile( + r"^\s*(3[01]|[12][0-9]|0?[1-9])\.(1[012]|0?[1-9])\.((?:19|20)\d{2})\s*$") + dateString = f"{self.timeEntryD.get()}.{self.timeEntryM.get().zfill(2)}.{self.timeEntryY.get()}" + date = pattern.match(dateString) + print(self.nameEntry.get()) + print(self.locationEntry.get()) + print(date) + print(self.descriptionEntry.get()) + if (self.nameEntry.get() and + self.locationEntry.get() and + date and self.descriptionEntry.get()): + self.parent.dbh.addEvent( + self.nameEntry.get(), + self.locationEntry.get(), + dateString, + self.descriptionEntry.get()) + else: + messagebox.showinfo( + "Missing arguments", + "It seems you didnt fill out all the info boxs \n" + + "please fill them all and try again.") + + +class CalendarPage(tk.Frame): + """Example page for Application.""" + + eventLabels = { + 0: "ID", + 1: "Name", + 2: "Location", + 3: "Date", + 4: "Description" + } + + def __init__(self, parent): + """ + Initialise the Example page. + + Arguments: + None + Returns: + None + """ + super().__init__() + + self.parent = parent + + self.create_widgets() + + def create_widgets(self): + """ + Create the pages widgets. + + Arguments: + None + Returns: + None + """ + # Create an add event button + self.addEventBtn = tk.Button(self, + text="[+] Add event", + command=lambda: self.parent.change_page( + AddEventPage)) + self.addEventBtn.grid() + # Fetch all events + events = self.parent.dbh.fetchEvents() + # Event format: + # (ID, name, location, Date, description)-- + self.grid_columnconfigure(0, weight=1) + + self.event_viewer = EventViewer(self) + self.event_viewer.grid(row=10, column=0) + for event in events: + self.event_viewer.add_event(event) From 8e6efacd17b96469c0e0ed824bf0c4b462e7d4ff Mon Sep 17 00:00:00 2001 From: Felix Date: Mon, 25 Feb 2019 23:17:34 +0000 Subject: [PATCH 23/41] Merge Fixing Apparently I can't do merge conflicts lmao --- project/UI/application.py | 40 ------------------------------------ project/UI/eventViewer.py | 24 ---------------------- project/backend/DBHandler.py | 8 -------- 3 files changed, 72 deletions(-) diff --git a/project/UI/application.py b/project/UI/application.py index bfefa3ae..9faa133c 100644 --- a/project/UI/application.py +++ b/project/UI/application.py @@ -7,11 +7,6 @@ from .eventViewer import EventViewer -from ..backend.DBHandler import DBHandler - -from .eventViewer import EventViewer - - class Application(tk.Tk): """Main Application class inheriting from tkinter.Tk.""" @@ -19,12 +14,9 @@ def __init__(self): """Initialise Application class.""" super().__init__() -<<<<<<< HEAD self.resizable(False, False) self.geometry("500x500") -======= ->>>>>>> Zomatree self.dbh = DBHandler() self.pages = {} @@ -85,12 +77,8 @@ def create_widgets(self): self.title.grid(row=0, column=0) self.button = tk.Button(self, text="Go to add event", -<<<<<<< HEAD - command=lambda: self.parent.change_page(CalendarPage)) -======= command=lambda: self.parent.change_page(CalendarPage)) ->>>>>>> Zomatree self.button.grid(row=1, column=0) @@ -136,33 +124,6 @@ def create_widgets(self): # Date self.date = tk.Label(self, text="Date", font=(24)) self.date.grid(row=3, sticky="E") -<<<<<<< HEAD - self.dateEntry = tk.Entry(self) - self.dateEntry.grid(row=3, column=1) - # Description - self.description = tk.Label(self, text="Description", font=(24)) - self.description.grid(row=4, sticky="E") - self.descriptionEntry = tk.Text(self, height=5, width=15) - self.descriptionEntry.grid(row=4, column=1) - # Submit Button - if len(self.nameEntry.get()) == 0 or \ - len(self.locationEntry.get()) == 0 or \ - len(self.dateEntry.get()) == 0 or \ - len(self.descriptionEntry.get("1.0")) == 0: - # Need some sort of UI goodness here! - print("[AddEventPage] Not all boxes filled") - # Break out - self.submitBtn = tk.Button( - self, - text="Submit ✔", - command=lambda: self.parent.dbh.addEvent( - self.nameEntry.get(), - self.locationEntry.get(), - self.dateEntry.get(), - self.descriptionEntry.get("1.0"))) - - self.submitBtn.grid() -======= self.dateSpinBoxs = tk.Frame(self) self.timeEntryD = tk.Spinbox(self.dateSpinBoxs, width=4, to=31) self.timeEntryM = tk.Spinbox(self.dateSpinBoxs, width=4, to=12) @@ -219,7 +180,6 @@ def inputCheck(self): "Missing arguments", "It seems you didnt fill out all the info boxs \n" + "please fill them all and try again.") ->>>>>>> Zomatree class CalendarPage(tk.Frame): diff --git a/project/UI/eventViewer.py b/project/UI/eventViewer.py index d4f8cf78..89cc1431 100644 --- a/project/UI/eventViewer.py +++ b/project/UI/eventViewer.py @@ -19,17 +19,6 @@ def __init__(self, parent): self.canvas = tk.Canvas(self) self.display_frame = tk.Frame(self.canvas) -<<<<<<< HEAD - self.scrollbar = tk.Scrollbar(self, orient="vertical", - command=self.canvas.yview) - self.canvas.configure(yscrollcommand=self.scrollbar.set) - - self.scrollbar.pack(side="right", fill="y") - self.canvas.pack(side="left", padx=10) - self.canvas.create_window((0, 0), window=self.display_frame, anchor="nw") - - self.display_frame.bind("", self.scrollMove) -======= self.scrollbar = tk.Scrollbar(self, orient="vertical", width=20, command=self.canvas.yview) self.canvas.configure(yscrollcommand=self.scrollbar.set) @@ -42,23 +31,11 @@ def __init__(self, parent): self.display_frame.bind("", self.scrollMove) self.display_frame.grid_columnconfigure(0, weight=1000) ->>>>>>> Felix self.events = {} def scrollMove(self, event): """Update canvas information from scrollbar movement.""" self.canvas.configure(scrollregion=self.canvas.bbox("all"), -<<<<<<< HEAD - width=300, height=500) - - def add_event(self, event): - """Add a new event to the viewer.""" - self.widgets = {} - - event_frame = tk.Frame(self.display_frame, height=200, width=300, - relief=tk.GROOVE, borderwidth=3) - event_frame.pack(fill="both", expand=True) -======= width=480, height=450) def add_event(self, event): @@ -66,7 +43,6 @@ def add_event(self, event): event_frame = tk.Frame(self.display_frame, relief=tk.GROOVE, borderwidth=3) event_frame.grid(column=0, pady=5, padx=5) ->>>>>>> Felix self.events.update({event: event_frame}) diff --git a/project/backend/DBHandler.py b/project/backend/DBHandler.py index a318afb2..78023d7d 100644 --- a/project/backend/DBHandler.py +++ b/project/backend/DBHandler.py @@ -39,9 +39,6 @@ def fetchEvents(self): return rows def addEvent(self, name, location, date, description): -<<<<<<< HEAD - """Create a new event and add it to the database.""" -======= """Create a new event and add it to the database. Arguments: @@ -52,7 +49,6 @@ def addEvent(self, name, location, date, description): Returns: None """ ->>>>>>> Throupy self.cursor.execute('''INSERT INTO events(name,location, date,description) VALUES(?,?,?,?)''', (name, @@ -83,10 +79,6 @@ def populate(self): VALUES(?,?,?,?)""", ("Meeting", "Office on 4th street", """Talk about upcoming -<<<<<<< HEAD - work events""",)) -======= work events""", "12/02")) ->>>>>>> Throupy self.conn.commit() From b83d45f7913043c9135efcc5851849bc52b762f7 Mon Sep 17 00:00:00 2001 From: Owen Throup <38217027+Throupy@users.noreply.github.com> Date: Wed, 27 Feb 2019 18:41:22 +0000 Subject: [PATCH 24/41] Login System (#8) Added new file: loginpage.py Added new methods: DBHandler.py: addUser() tryLogin() Still need to implelement what actually happens when the user logs in. IE a redirect to calendar.py. Basic UI has been built for the login system with message boxes and stuff, take a look. --- project/backend/DBHandler.py | 54 ++++++++++++++++++++++++- project/backend/{events.db => app.db} | Bin 8192 -> 12288 bytes project/backend/calender.py | 5 ++- project/backend/pages/loginpage.py | 45 +++++++++++++++++++++ project/backend/utils/jsonMessage.json | 5 +++ 5 files changed, 106 insertions(+), 3 deletions(-) rename project/backend/{events.db => app.db} (55%) create mode 100644 project/backend/pages/loginpage.py create mode 100644 project/backend/utils/jsonMessage.json diff --git a/project/backend/DBHandler.py b/project/backend/DBHandler.py index 78023d7d..6297133d 100644 --- a/project/backend/DBHandler.py +++ b/project/backend/DBHandler.py @@ -1,5 +1,7 @@ """Database handling for calandar application.""" import sqlite3 +import json +from tkinter import messagebox class DBHandler: @@ -13,7 +15,7 @@ def __init__(self): Returns: None """ - self.conn = sqlite3.connect("events.db") + self.conn = sqlite3.connect("app.db") self.cursor = self.conn.cursor() self.cursor.execute(""" CREATE TABLE IF NOT EXISTS events( @@ -22,7 +24,13 @@ def __init__(self): location TEXT, date TEXT, description TEXT)""") - + self.cursor.execute(""" + CREATE TABLE IF NOT EXISTS users( + ID INTEGER PRIMARY KEY, + username TEXT, + password TEXT)""") + with open("utils/jsonMessage.json") as jsonMessages: + self.jsonMessages = json.load(jsonMessages) # self.populate() def fetchEvents(self): @@ -70,6 +78,48 @@ def removeEvent(self, id): print(f"Deleted event with ID: {id}") self.conn.commit() + def addUser(self, username, password): + """ + Add a user to the database. + + Arguments: + entryName - the name to be added, + entryPassword - the password for the user + Returns: + None + """ + self.cursor.execute('''INSERT INTO users(username,password) + VALUES(?,?)''', (username, password)) + self.conn.commit() + + def tryLogin(self, username, password): + """Attempt user login. + + Arguments: + username - user's username + password - user's password + Returns: + None + """ + if len(username) < 1 or len(password) < 1: + messagebox.showerror("Error", + self.jsonMessages['populateLogin'] + ) + return + self.cursor.execute("""SELECT * FROM users WHERE username=? AND password=?""", + (username, password)) + rows = self.cursor.fetchall() + if len(rows) == 0: + addUserMB = messagebox.askyesno("No user found", + self.jsonMessages['noUser']) + # If they select 'yes' on the messagebox + if addUserMB: + self.addUser(username, password) + messagebox.showinfo("Success", + self.jsonMessages['userAdded']) + return + # LOG IN THE USER, MAYBE A METHOD IN MAIN APP + # TESTING - ONLY USED IN DEVELOPMENT. REMOVE UPON RELEASE!!! def populate(self): """Use to populate the database with sample data.""" diff --git a/project/backend/events.db b/project/backend/app.db similarity index 55% rename from project/backend/events.db rename to project/backend/app.db index 74c0f514473f707e60870c21834322af75ecb552..aca62c99032aefe301c5b723f3d00bfd4419bb28 100644 GIT binary patch delta 194 zcmZp0Xh@hKEy%*az`zW|Fu*iX#~3K6Cvk!oD8$4!kAdHiZ{Eg2JwEM50VZ~FadF1R z`jW(?oYd0d)S_ZA!R#F5>KNjx5aQ_MnjFt>%>ri3;+N(tNGvWc&o4?*2yu-F z(VT3^e}NTboxsMz1AH4BtQdK~R`K6w;D675A0jBssL02}!XPT?mg5Lu9)E?xxltmk$CGDaI;sKw@lMi4# z_(YyugBSy-$A&o5-L|tkn`wWW+2ntDQE{YzrssFKggjXxl#&AgLP%Eii0UJw>LogI z)bqpt%d%v9^(CRAXljS3hK2-?01`j~NB{{S0VIF~kN^@u0!Uys2n;GTmd<48Lm+v* zEyS&GWiY%)N+v5>46Nc|g~4!aV+qF0I0EC;V#mycbJM66%^H+hZEGUV0xQ6lqkgQOmlPs#oGbKDqS%dfMs9r%?<00|%g zB!C2v01`j~NZ=n6xL+%z2ZgE-(s8fPnoY+Rpmf5nyn#UaYIsM_X}ZPRE#P&pC!yE1 zy^e~VkRM~JWx9Lk`K?c((_f5{@RG+uOrF{!Z=wCUN*>~#M?=Kkp9?X$I%2}ZenJ;i XsjZiPDRV8KQ%%=&ZAz`fx3YZ)ASF-? diff --git a/project/backend/calender.py b/project/backend/calender.py index 42828ba9..844aac8e 100644 --- a/project/backend/calender.py +++ b/project/backend/calender.py @@ -3,6 +3,7 @@ from DBHandler import DBHandler from pages.addeventpage import AddEventPage from pages.calendarpage import CalendarPage +from pages.loginpage import LoginPage class Application(tk.Tk): @@ -39,7 +40,9 @@ def create_pages(self): self.pages[CalendarPage] = CalendarPage(self) - self.change_page(CalendarPage) + self.pages[LoginPage] = LoginPage(self) + + self.change_page(LoginPage) def change_page(self, new_page): """ diff --git a/project/backend/pages/loginpage.py b/project/backend/pages/loginpage.py new file mode 100644 index 00000000..a43aba5a --- /dev/null +++ b/project/backend/pages/loginpage.py @@ -0,0 +1,45 @@ +"""Login page for the calendar application.""" +import tkinter as tk + + +class LoginPage(tk.Frame): + """Page where you can add events to the calendar.""" + + def __init__(self, parent): + """ + Initialise the Add Event page. + + Arguments: + None + Returns: + None + """ + super().__init__() + self.parent = parent + self.create_widgets() + + def create_widgets(self): + """ + Create the pages widgets. + + Arguments: + None + Returns: + None + """ + self.title = tk.Label(self, text="Please log-in", font=(24)) + self.title.grid(column=1) + self.usernameLabel = tk.Label(self, text="Username") + self.usernameLabel.grid(row=1, sticky="E") + self.passwordLabel = tk.Label(self, text="Password") + self.passwordLabel.grid(row=2, sticky="E") + self.usernameEntry = tk.Entry(self) + self.usernameEntry.grid(row=1, column=1) + self.passwordEntry = tk.Entry(self, show="*") + self.passwordEntry.grid(row=2, column=1) + self.loginButton = tk.Button(self, + text="Login", + command=lambda: + self.parent.dbh.tryLogin(self.usernameEntry.get(), + self.passwordEntry.get())) + self.loginButton.grid(row=4, column=1) diff --git a/project/backend/utils/jsonMessage.json b/project/backend/utils/jsonMessage.json new file mode 100644 index 00000000..29416f04 --- /dev/null +++ b/project/backend/utils/jsonMessage.json @@ -0,0 +1,5 @@ +{ + "populateLogin":"You must populate the username and password fields!", + "noUser":"No user found with these credentials, would you like to add the user with this username and password?", + "userAdded":"User has been added to the database!" +} From 6c7f90abdb1119c0ba116e1b156f6e0009c799b4 Mon Sep 17 00:00:00 2001 From: zomatree <39768508+zomatree@users.noreply.github.com> Date: Wed, 27 Feb 2019 20:58:43 +0000 Subject: [PATCH 25/41] Update application.py (#9) added more indepth date checking and addedback button :smile: --- project/UI/application.py | 56 +++++++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 14 deletions(-) diff --git a/project/UI/application.py b/project/UI/application.py index 9faa133c..892c6c6d 100644 --- a/project/UI/application.py +++ b/project/UI/application.py @@ -1,7 +1,7 @@ """Green Greenhouses Calendar Application.""" import tkinter as tk from tkinter import messagebox -import re + from ..backend.DBHandler import DBHandler from .eventViewer import EventViewer @@ -99,6 +99,20 @@ def __init__(self, parent): self.parent = parent self.create_widgets() + self.months = { + "1": 31, + "2": 28, + "3": 31, + "4": 30, + "5": 31, + "6": 30, + "7": 31, + "8": 31, + "9": 30, + "10": 31, + "11": 30, + "12": 31 + } def create_widgets(self): """ @@ -126,10 +140,10 @@ def create_widgets(self): self.date.grid(row=3, sticky="E") self.dateSpinBoxs = tk.Frame(self) self.timeEntryD = tk.Spinbox(self.dateSpinBoxs, width=4, to=31) - self.timeEntryM = tk.Spinbox(self.dateSpinBoxs, width=4, to=12) + self.timeEntryM = tk.Spinbox(self.dateSpinBoxs, width=5, to=12) self.timeEntryY = tk.Spinbox( self.dateSpinBoxs, - width=4, + width=5, from_=2019, to=3000) self.timeEntryD.grid(row=3, column=1) @@ -148,6 +162,18 @@ def create_widgets(self): text="Submit ✔", command=lambda: self.inputCheck()) self.submitBtn.grid() + # back button + self.back = tk.Button( + self, + text="Back", + command=lambda: self.parent.change_page(CalendarPage)) + self.back.grid(row=5, column=1, sticky="w") + + def IsDaysCorrect(self, list): + """""" + if self.months[str(int(list[1]))] >= int(list[0]): + return True + return False def inputCheck(self): """ @@ -159,27 +185,29 @@ def inputCheck(self): Returns: None """ - pattern = re.compile( - r"^\s*(3[01]|[12][0-9]|0?[1-9])\.(1[012]|0?[1-9])\.((?:19|20)\d{2})\s*$") - dateString = f"{self.timeEntryD.get()}.{self.timeEntryM.get().zfill(2)}.{self.timeEntryY.get()}" - date = pattern.match(dateString) - print(self.nameEntry.get()) - print(self.locationEntry.get()) - print(date) - print(self.descriptionEntry.get()) + + dateList = [ + self.timeEntryD.get(), + self.timeEntryM.get(), + self.timeEntryY.get()] + print(self.IsDaysCorrect(dateList)) + if (self.nameEntry.get() and self.locationEntry.get() and - date and self.descriptionEntry.get()): + self.IsDaysCorrect(dateList) and + self.descriptionEntry.get()): self.parent.dbh.addEvent( self.nameEntry.get(), self.locationEntry.get(), - dateString, + ".".join(dateList), self.descriptionEntry.get()) else: messagebox.showinfo( "Missing arguments", "It seems you didnt fill out all the info boxs \n" + - "please fill them all and try again.") + "Or you didnt fill the date correctly\n" + + "please fill them all correctly and try again.") + self.parent.change_page(CalendarPage) class CalendarPage(tk.Frame): From e269c0a7b946c42056533d7dab900ea106e9abe5 Mon Sep 17 00:00:00 2001 From: Felix Date: Wed, 27 Feb 2019 21:24:15 +0000 Subject: [PATCH 26/41] Fixed jsonMessages path Updated path to reflect loading from different path --- project/backend/DBHandler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/backend/DBHandler.py b/project/backend/DBHandler.py index 6297133d..912b4f73 100644 --- a/project/backend/DBHandler.py +++ b/project/backend/DBHandler.py @@ -29,7 +29,7 @@ def __init__(self): ID INTEGER PRIMARY KEY, username TEXT, password TEXT)""") - with open("utils/jsonMessage.json") as jsonMessages: + with open("./project/backend/utils/jsonMessage.json") as jsonMessages: self.jsonMessages = json.load(jsonMessages) # self.populate() From 85ba2957c1ce19c2d641c43f97690b33bd7e6873 Mon Sep 17 00:00:00 2001 From: Felix Date: Thu, 28 Feb 2019 20:49:42 +0000 Subject: [PATCH 27/41] Added Dark Mode Dark mode added, currently toggled by pressing Q on any page. --- project/UI/application.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/project/UI/application.py b/project/UI/application.py index 892c6c6d..1e6023cc 100644 --- a/project/UI/application.py +++ b/project/UI/application.py @@ -23,6 +23,20 @@ def __init__(self): self.create_pages() + self.tk_setPalette(background="#F0F0F0", foreground="#000000") + self.dark_mode = False + self.bind("q", self.switch) + + def switch(self, event): + """Switch the application between light and dark mode.""" + if self.dark_mode: + self.tk_setPalette(background="#F0F0F0", foreground="#000000") + + else: + self.tk_setPalette(background="#292D32", foreground="#2e3237") + + self.dark_mode = not self.dark_mode + def create_pages(self): """ Create the applications pages. From 29f29554b27b9932355d0527bd1d191ecfaf4027 Mon Sep 17 00:00:00 2001 From: zomatree <39768508+zomatree@users.noreply.github.com> Date: Thu, 28 Feb 2019 20:51:11 +0000 Subject: [PATCH 28/41] Zomatree (#12) * Update application.py added more indepth date checking and addedback button :smile: * fixed bug that alows you to have month be 0 * fixed linting and bug where month/day could be 0 --- .gitignore | 2 +- project/UI/application.py | 39 +++++++++++++++++++++++++-------------- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/.gitignore b/.gitignore index 35aa063e..b03a35e7 100644 --- a/.gitignore +++ b/.gitignore @@ -102,5 +102,5 @@ venv.bak/ # mypy .mypy_cache/ -project/CODEJAM-4-26a1748ad4a6.json .gitignore +app.db diff --git a/project/UI/application.py b/project/UI/application.py index 1e6023cc..0780370f 100644 --- a/project/UI/application.py +++ b/project/UI/application.py @@ -153,13 +153,21 @@ def create_widgets(self): self.date = tk.Label(self, text="Date", font=(24)) self.date.grid(row=3, sticky="E") self.dateSpinBoxs = tk.Frame(self) - self.timeEntryD = tk.Spinbox(self.dateSpinBoxs, width=4, to=31) - self.timeEntryM = tk.Spinbox(self.dateSpinBoxs, width=5, to=12) + self.timeEntryD = tk.Spinbox(self.dateSpinBoxs, + width=4, + from_=1, + to=31) + + self.timeEntryM = tk.Spinbox(self.dateSpinBoxs, + width=5, + from_=1, + to=12) + self.timeEntryY = tk.Spinbox( - self.dateSpinBoxs, - width=5, - from_=2019, - to=3000) + self.dateSpinBoxs, + width=5, + from_=2019, + to=3000) self.timeEntryD.grid(row=3, column=1) self.timeEntryM.grid(row=3, column=2) self.timeEntryY.grid(row=3, column=3) @@ -169,6 +177,7 @@ def create_widgets(self): self.description.grid(row=4, sticky="E") self.descriptionEntry = tk.Entry(self) self.descriptionEntry.grid(row=4, column=1) + # Submit Button self.submitBtn = tk.Button( @@ -178,9 +187,10 @@ def create_widgets(self): self.submitBtn.grid() # back button self.back = tk.Button( - self, - text="Back", - command=lambda: self.parent.change_page(CalendarPage)) + self, + text="Back", + command=lambda: + self.parent.change_page(CalendarPage)) self.back.grid(row=5, column=1, sticky="w") def IsDaysCorrect(self, list): @@ -206,15 +216,16 @@ def inputCheck(self): self.timeEntryY.get()] print(self.IsDaysCorrect(dateList)) - if (self.nameEntry.get() and + if ( + self.nameEntry.get() and self.locationEntry.get() and self.IsDaysCorrect(dateList) and self.descriptionEntry.get()): self.parent.dbh.addEvent( - self.nameEntry.get(), - self.locationEntry.get(), - ".".join(dateList), - self.descriptionEntry.get()) + self.nameEntry.get(), + self.locationEntry.get(), + ".".join(dateList), + self.descriptionEntry.get()) else: messagebox.showinfo( "Missing arguments", From 4dc3e186a9927c271a03b0147f08238644f0398b Mon Sep 17 00:00:00 2001 From: Felix Date: Thu, 28 Feb 2019 20:54:12 +0000 Subject: [PATCH 29/41] Delete events.db --- events.db | Bin 8192 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 events.db diff --git a/events.db b/events.db deleted file mode 100644 index daf0fde0716454f829e29fba0aa93dd3d444d8a2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 zcmeI#&n^Q&90%~3s_madM)XikG{!+fBB&l*EtWKj+U`M*qdV+YyCb`+jW}`f03N^t zco8R0;vr1altzifP4fL_XZANUzqx#FQ$MNtvE=6}?1-3`$uyyqY;jHq$>@>LV;HK7 zcI$yDClP3k7-~#p0|j zWmg7qG?)`Rwq-gNcg*do#Rq#!S^g!JU0ykItbNPoHM??X+6{hSHCD#@0@0D&u}+=w zqqb^_*jK?1$F9&X`tNVLGHQnY)yL)K{@Xmw6k%`dl|8d3_Q)RCt=>Q&009U<00Izz z00bZa0SG_<0ucDCKsIdb=8qQPll!P+WN*?Y15yf2Fc~}>^P84PdQ#F<=#7zx?uYN From b1d2d22aadb79c2ec57af7a0e18e5f314b88b827 Mon Sep 17 00:00:00 2001 From: zomatree <39768508+zomatree@users.noreply.github.com> Date: Sun, 3 Mar 2019 17:02:37 +0000 Subject: [PATCH 30/41] Zomatree (#13) * Update application.py added more indepth date checking and addedback button :smile: * fixed bug that alows you to have month be 0 * fixed linting and bug where month/day could be 0 * Update application.py changd inputs to tk.Text from tk.Entry and resized the entry boxes also when you create a event is updates the list * Update application.py added the start of horrible looks and the hatrid * updated __main__ and app.py this one is anoying all black, text is near black to click you have to hold left click when clicking a button a popup will apear press enter then let go of left click on the let go the button will click also closing the app may be hard * added more hatrid * removed random import * fixed linting issue --- Pipfile | 2 + Pipfile.lock | 63 ++++++++++++++-- project/UI/application.py | 154 +++++++++++++++++++++++++------------- project/UI/eventViewer.py | 19 +++-- project/__main__.py | 11 +++ 5 files changed, 186 insertions(+), 63 deletions(-) diff --git a/Pipfile b/Pipfile index 950f516e..093ccf15 100644 --- a/Pipfile +++ b/Pipfile @@ -5,9 +5,11 @@ verify_ssl = true [dev-packages] flake8 = "*" +autopep8 = "*" [packages] flake8 = "*" +googletrans = "*" [requires] python_version = "3.7" diff --git a/Pipfile.lock b/Pipfile.lock index fc3cef26..d99005ce 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "6e90e4e61e002075aea15d26a0b7253050f5355dd737991fd59d9a7ae9a60f2b" + "sha256": "13553bd5f9066cb1a19d9a178d8292c247deabb4d8ce7aa337c7aec6cba962f0" }, "pipfile-spec": 6, "requires": { @@ -16,6 +16,20 @@ ] }, "default": { + "certifi": { + "hashes": [ + "sha256:47f9c83ef4c0c621eaef743f133f09fa8a74a9b75f037e8624f83bd1b6626cb7", + "sha256:993f830721089fef441cdfeb4b2c8c9df86f0c63239f06bd025a76a7daddb033" + ], + "version": "==2018.11.29" + }, + "chardet": { + "hashes": [ + "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", + "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" + ], + "version": "==3.0.4" + }, "entrypoints": { "hashes": [ "sha256:589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19", @@ -31,6 +45,20 @@ "index": "pypi", "version": "==3.7.7" }, + "googletrans": { + "hashes": [ + "sha256:bb4e2a6ee72a24870e696a14238b7305f855a05206ecae10bd50052651984cc5" + ], + "index": "pypi", + "version": "==2.4.0" + }, + "idna": { + "hashes": [ + "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", + "sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c" + ], + "version": "==2.8" + }, "mccabe": { "hashes": [ "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", @@ -47,13 +75,34 @@ }, "pyflakes": { "hashes": [ - "sha256:5e8c00e30c464c99e0b501dc160b13a14af7f27d4dffb529c556e30a159e231d", - "sha256:f277f9ca3e55de669fba45b7393a1449009cff5a37d1af10ebb76c52765269cd" + "sha256:17dbeb2e3f4d772725c777fabc446d5634d1038f234e77343108ce445ea69ce0", + "sha256:d976835886f8c5b31d47970ed689944a0262b5f3afa00a5a7b4dc81e5449f8a2" + ], + "version": "==2.1.1" + }, + "requests": { + "hashes": [ + "sha256:502a824f31acdacb3a35b6690b5fbf0bc41d63a24a45c4004352b0242707598e", + "sha256:7bf2a778576d825600030a110f3c0e3e8edc51dfaafe1c146e39a2027784957b" ], - "version": "==2.1.0" + "version": "==2.21.0" + }, + "urllib3": { + "hashes": [ + "sha256:61bf29cada3fc2fbefad4fdf059ea4bd1b4a86d2b6d15e1c7c0b582b9752fe39", + "sha256:de9529817c93f27c8ccbfead6985011db27bd0ddfcdb2d86f3f663385c6a9c22" + ], + "version": "==1.24.1" } }, "develop": { + "autopep8": { + "hashes": [ + "sha256:33d2b5325b7e1afb4240814fe982eea3a92ebea712869bfd08b3c0393404248c" + ], + "index": "pypi", + "version": "==1.4.3" + }, "entrypoints": { "hashes": [ "sha256:589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19", @@ -85,10 +134,10 @@ }, "pyflakes": { "hashes": [ - "sha256:5e8c00e30c464c99e0b501dc160b13a14af7f27d4dffb529c556e30a159e231d", - "sha256:f277f9ca3e55de669fba45b7393a1449009cff5a37d1af10ebb76c52765269cd" + "sha256:17dbeb2e3f4d772725c777fabc446d5634d1038f234e77343108ce445ea69ce0", + "sha256:d976835886f8c5b31d47970ed689944a0262b5f3afa00a5a7b4dc81e5449f8a2" ], - "version": "==2.1.0" + "version": "==2.1.1" } } } diff --git a/project/UI/application.py b/project/UI/application.py index 0780370f..66f06424 100644 --- a/project/UI/application.py +++ b/project/UI/application.py @@ -1,10 +1,10 @@ """Green Greenhouses Calendar Application.""" import tkinter as tk from tkinter import messagebox - from ..backend.DBHandler import DBHandler - from .eventViewer import EventViewer +import string +from ..backend.utils.translator import translate class Application(tk.Tk): @@ -16,6 +16,7 @@ def __init__(self): self.resizable(False, False) self.geometry("500x500") + self.configure(background="#000000") self.dbh = DBHandler() @@ -75,7 +76,7 @@ def __init__(self, parent): super().__init__(parent) self.parent = parent - + self.configure(background="#000000") self.create_widgets() def create_widgets(self): @@ -87,14 +88,23 @@ def create_widgets(self): Returns: N/A """ - self.title = tk.Label(self, text="Hello World") + self.title = tk.Label( + self, fg="#464646", + text="Hello World", + bg="#000000") self.title.grid(row=0, column=0) - self.button = tk.Button(self, text="Go to add event", + self.button = tk.Button(self, text="Go to events", bg="#000000", command=lambda: self.parent.change_page(CalendarPage)) self.button.grid(row=1, column=0) + self.addEventBtn = tk.Button(self, bg="#000000", + text="[+] Add event", + command=lambda: self.parent.change_page( + AddEventPage)) + self.addEventBtn.grid() + class AddEventPage(tk.Frame): """Page where you can add events to the calendar.""" @@ -111,7 +121,7 @@ def __init__(self, parent): super().__init__() self.parent = parent - + self.configure(background="#000000") self.create_widgets() self.months = { "1": 31, @@ -125,8 +135,7 @@ def __init__(self, parent): "9": 30, "10": 31, "11": 30, - "12": 31 - } + "12": 31} def create_widgets(self): """ @@ -137,61 +146,92 @@ def create_widgets(self): Returns: N/A """ - self.title = tk.Label(self, text="Add an event", font=(30)) + self.title = tk.Label( + self, fg="#464646", + text="Add an event", font=(30), + bg="#000000") self.title.grid(column=1) # Name - self.name = tk.Label(self, text="Name", font=(24)) + self.name = tk.Label( + self, fg="#464646", + text="Name ", + font=(24), bg="#000000") self.name.grid(row=1, sticky="E") - self.nameEntry = tk.Entry(self) + self.nameEntry = tk.Text( + self, fg="#464646", + height=2, width=49, bg="#000000") self.nameEntry.grid(row=1, column=1) # Location - self.location = tk.Label(self, text="Location", font=(24)) + self.location = tk.Label( + self, fg="#464646", + text="Location ", + font=(24), bg="#000000") self.location.grid(row=2, sticky="E") - self.locationEntry = tk.Entry(self) + self.locationEntry = tk.Text( + self, fg="#464646", + height=2, width=49, bg="#000000") self.locationEntry.grid(row=2, column=1) # Date - self.date = tk.Label(self, text="Date", font=(24)) + self.date = tk.Label( + self, fg="#464646", + text="Date ", + font=(24), bg="#000000") self.date.grid(row=3, sticky="E") - self.dateSpinBoxs = tk.Frame(self) + self.dateSpinBoxs = tk.Frame(self, bg="#000000") self.timeEntryD = tk.Spinbox(self.dateSpinBoxs, - width=4, + width=14, from_=1, - to=31) + to=31, + bg="#000000", + fg="#464646",) self.timeEntryM = tk.Spinbox(self.dateSpinBoxs, - width=5, + width=15, from_=1, - to=12) + to=12, + bg="#000000", + fg="#464646",) - self.timeEntryY = tk.Spinbox( - self.dateSpinBoxs, - width=5, + self.timeEntryY = tk.Spinbox(self.dateSpinBoxs, + width=14, from_=2019, - to=3000) + to=3000, + bg="#000000", + fg="#464646") + self.timeEntryD.grid(row=3, column=1) self.timeEntryM.grid(row=3, column=2) self.timeEntryY.grid(row=3, column=3) self.dateSpinBoxs.grid(row=3, column=1) # Description - self.description = tk.Label(self, text="Description", font=(24)) - self.description.grid(row=4, sticky="E") - self.descriptionEntry = tk.Entry(self) + self.description = tk.Label( + self, fg="#464646", + text="Description ", + font=(24), bg="#000000") + self.description.grid(row=4, sticky="N") + self.descriptionEntry = tk.Text( + self, height=20, + width=49, bg="#000000", + fg="#464646") self.descriptionEntry.grid(row=4, column=1) # Submit Button - + self.submitBack = tk.Frame(self, bg="#000000") self.submitBtn = tk.Button( - self, + self.submitBack, text="Submit ✔", - command=lambda: self.inputCheck()) - self.submitBtn.grid() + command=lambda: self.inputCheck(), + bg="#000000") + self.submitBtn.grid(row=1, sticky="W") # back button self.back = tk.Button( - self, - text="Back", - command=lambda: - self.parent.change_page(CalendarPage)) - self.back.grid(row=5, column=1, sticky="w") + self.submitBack, + text="Back", + command=lambda: + self.parent.change_page(HomePage), + bg="#000000") + self.back.grid(row=1, column=1, sticky="W") + self.submitBack.grid(column=1) def IsDaysCorrect(self, list): """""" @@ -214,25 +254,35 @@ def inputCheck(self): self.timeEntryD.get(), self.timeEntryM.get(), self.timeEntryY.get()] - print(self.IsDaysCorrect(dateList)) if ( - self.nameEntry.get() and - self.locationEntry.get() and + any( + letter.lower() in self.descriptionEntry.get("1.0", tk.END) + for letter in string.ascii_lowercase) and + any( + letter.lower() in self.locationEntry.get("1.0", tk.END) + for letter in string.ascii_lowercase) and self.IsDaysCorrect(dateList) and - self.descriptionEntry.get()): + any( + letter.lower() in self.nameEntry.get("1.0", tk.END) + for letter in string.ascii_lowercase)): self.parent.dbh.addEvent( - self.nameEntry.get(), - self.locationEntry.get(), - ".".join(dateList), - self.descriptionEntry.get()) + translate( + self.nameEntry.get("1.0", tk.END)), + translate( + self.locationEntry.get("1.0", tk.END)), + ".".join(dateList), + translate( + self.descriptionEntry.get("1.0", tk.END))) + else: messagebox.showinfo( "Missing arguments", "It seems you didnt fill out all the info boxs \n" + "Or you didnt fill the date correctly\n" + "please fill them all correctly and try again.") - self.parent.change_page(CalendarPage) + self.parent.pages[CalendarPage].create_widgets() + self.parent.change_page(HomePage) class CalendarPage(tk.Frame): @@ -258,7 +308,7 @@ def __init__(self, parent): super().__init__() self.parent = parent - + self.configure(background="#000000") self.create_widgets() def create_widgets(self): @@ -270,12 +320,14 @@ def create_widgets(self): Returns: None """ - # Create an add event button - self.addEventBtn = tk.Button(self, - text="[+] Add event", - command=lambda: self.parent.change_page( - AddEventPage)) - self.addEventBtn.grid() + self.back = tk.Button( + self, + text="Back", + bg="#000000", + command=lambda: + self.parent.change_page(HomePage)) + + self.back.grid(sticky="W") # Fetch all events events = self.parent.dbh.fetchEvents() # Event format: diff --git a/project/UI/eventViewer.py b/project/UI/eventViewer.py index 89cc1431..c5a5d2bc 100644 --- a/project/UI/eventViewer.py +++ b/project/UI/eventViewer.py @@ -21,16 +21,21 @@ def __init__(self, parent): self.display_frame = tk.Frame(self.canvas) self.scrollbar = tk.Scrollbar(self, orient="vertical", width=20, command=self.canvas.yview) - self.canvas.configure(yscrollcommand=self.scrollbar.set) + self.canvas.configure( + yscrollcommand=self.scrollbar.set, + background="#000000") self.grid_rowconfigure(0, weight=100) self.scrollbar.grid(row=0, column=1, sticky="ns") self.canvas.grid(row=0, column=0) - self.canvas.create_window((240, 0), window=self.display_frame, anchor="n") + self.canvas.create_window( + (240, 0), + window=self.display_frame, + anchor="n") self.display_frame.bind("", self.scrollMove) self.display_frame.grid_columnconfigure(0, weight=1000) - + self.display_frame.configure(bg="#000000") self.events = {} def scrollMove(self, event): @@ -41,11 +46,15 @@ def scrollMove(self, event): def add_event(self, event): """Add a new event to the viewer.""" event_frame = tk.Frame(self.display_frame, - relief=tk.GROOVE, borderwidth=3) + relief=tk.GROOVE, borderwidth=3, bg="#000000") event_frame.grid(column=0, pady=5, padx=5) self.events.update({event: event_frame}) for key, name in self.eventLabels.items(): - widget = tk.Label(event_frame, text=name+" - "+str(event[key])) + widget = tk.Label( + event_frame, + text=name + " - " + str(event[key]), + bg="#000000", + fg="#464646") widget.pack() diff --git a/project/__main__.py b/project/__main__.py index 529061e0..e2b1411c 100644 --- a/project/__main__.py +++ b/project/__main__.py @@ -1,5 +1,16 @@ from .UI.application import Application +from tkinter import messagebox as mb + + +def protocal(): + mb.askyesno(None, "Are you sure you want to quit?") + return protocal() + if __name__ == "__main__": app = Application() + app.bind("", lambda event: mb.showinfo( + "UPDATE!", + "we have updated our privacy policy")) + app.protocol("WM_DELETE_WINDOW", protocal) app.mainloop() From 18fdd04820c07c2fca7842bcaeb740153c978aa2 Mon Sep 17 00:00:00 2001 From: FelixR Date: Sun, 3 Mar 2019 17:25:16 +0000 Subject: [PATCH 31/41] Undid changes (#15) Undid things done poorly or already done previously. --- project/UI/application.py | 68 +++++++++-------------- project/UI/eventViewer.py | 10 +--- project/__main__.py | 11 ---- project/backend/{ => utils}/translator.py | 0 4 files changed, 29 insertions(+), 60 deletions(-) rename project/backend/{ => utils}/translator.py (100%) diff --git a/project/UI/application.py b/project/UI/application.py index 66f06424..aa21ff33 100644 --- a/project/UI/application.py +++ b/project/UI/application.py @@ -16,7 +16,6 @@ def __init__(self): self.resizable(False, False) self.geometry("500x500") - self.configure(background="#000000") self.dbh = DBHandler() @@ -76,7 +75,6 @@ def __init__(self, parent): super().__init__(parent) self.parent = parent - self.configure(background="#000000") self.create_widgets() def create_widgets(self): @@ -89,17 +87,16 @@ def create_widgets(self): N/A """ self.title = tk.Label( - self, fg="#464646", - text="Hello World", - bg="#000000") + self, + text="Hello World") self.title.grid(row=0, column=0) - self.button = tk.Button(self, text="Go to events", bg="#000000", + self.button = tk.Button(self, text="Go to events", command=lambda: self.parent.change_page(CalendarPage)) self.button.grid(row=1, column=0) - self.addEventBtn = tk.Button(self, bg="#000000", + self.addEventBtn = tk.Button(self, text="[+] Add event", command=lambda: self.parent.change_page( AddEventPage)) @@ -121,7 +118,6 @@ def __init__(self, parent): super().__init__() self.parent = parent - self.configure(background="#000000") self.create_widgets() self.months = { "1": 31, @@ -147,57 +143,50 @@ def create_widgets(self): N/A """ self.title = tk.Label( - self, fg="#464646", - text="Add an event", font=(30), - bg="#000000") + self, + text="Add an event", font=(30)) self.title.grid(column=1) # Name self.name = tk.Label( - self, fg="#464646", + self, text="Name ", - font=(24), bg="#000000") + font=(24)) self.name.grid(row=1, sticky="E") self.nameEntry = tk.Text( - self, fg="#464646", - height=2, width=49, bg="#000000") + self, + height=2, width=49) self.nameEntry.grid(row=1, column=1) # Location self.location = tk.Label( - self, fg="#464646", + self, text="Location ", - font=(24), bg="#000000") + font=(24),) self.location.grid(row=2, sticky="E") self.locationEntry = tk.Text( - self, fg="#464646", - height=2, width=49, bg="#000000") + self, + height=2, width=49) self.locationEntry.grid(row=2, column=1) # Date self.date = tk.Label( - self, fg="#464646", + self, text="Date ", - font=(24), bg="#000000") + font=(24)) self.date.grid(row=3, sticky="E") - self.dateSpinBoxs = tk.Frame(self, bg="#000000") + self.dateSpinBoxs = tk.Frame(self) self.timeEntryD = tk.Spinbox(self.dateSpinBoxs, width=14, from_=1, - to=31, - bg="#000000", - fg="#464646",) + to=31) self.timeEntryM = tk.Spinbox(self.dateSpinBoxs, width=15, from_=1, - to=12, - bg="#000000", - fg="#464646",) + to=12) self.timeEntryY = tk.Spinbox(self.dateSpinBoxs, width=14, from_=2019, - to=3000, - bg="#000000", - fg="#464646") + to=3000) self.timeEntryD.grid(row=3, column=1) self.timeEntryM.grid(row=3, column=2) @@ -205,31 +194,28 @@ def create_widgets(self): self.dateSpinBoxs.grid(row=3, column=1) # Description self.description = tk.Label( - self, fg="#464646", + self, text="Description ", - font=(24), bg="#000000") + font=(24)) self.description.grid(row=4, sticky="N") self.descriptionEntry = tk.Text( self, height=20, - width=49, bg="#000000", - fg="#464646") + width=49) self.descriptionEntry.grid(row=4, column=1) # Submit Button - self.submitBack = tk.Frame(self, bg="#000000") + self.submitBack = tk.Frame(self) self.submitBtn = tk.Button( self.submitBack, text="Submit ✔", - command=lambda: self.inputCheck(), - bg="#000000") + command=lambda: self.inputCheck()) self.submitBtn.grid(row=1, sticky="W") # back button self.back = tk.Button( self.submitBack, text="Back", command=lambda: - self.parent.change_page(HomePage), - bg="#000000") + self.parent.change_page(HomePage)) self.back.grid(row=1, column=1, sticky="W") self.submitBack.grid(column=1) @@ -308,7 +294,6 @@ def __init__(self, parent): super().__init__() self.parent = parent - self.configure(background="#000000") self.create_widgets() def create_widgets(self): @@ -323,7 +308,6 @@ def create_widgets(self): self.back = tk.Button( self, text="Back", - bg="#000000", command=lambda: self.parent.change_page(HomePage)) diff --git a/project/UI/eventViewer.py b/project/UI/eventViewer.py index c5a5d2bc..136e0c84 100644 --- a/project/UI/eventViewer.py +++ b/project/UI/eventViewer.py @@ -22,8 +22,7 @@ def __init__(self, parent): self.scrollbar = tk.Scrollbar(self, orient="vertical", width=20, command=self.canvas.yview) self.canvas.configure( - yscrollcommand=self.scrollbar.set, - background="#000000") + yscrollcommand=self.scrollbar.set) self.grid_rowconfigure(0, weight=100) self.scrollbar.grid(row=0, column=1, sticky="ns") @@ -35,7 +34,6 @@ def __init__(self, parent): self.display_frame.bind("", self.scrollMove) self.display_frame.grid_columnconfigure(0, weight=1000) - self.display_frame.configure(bg="#000000") self.events = {} def scrollMove(self, event): @@ -46,7 +44,7 @@ def scrollMove(self, event): def add_event(self, event): """Add a new event to the viewer.""" event_frame = tk.Frame(self.display_frame, - relief=tk.GROOVE, borderwidth=3, bg="#000000") + relief=tk.GROOVE, borderwidth=3) event_frame.grid(column=0, pady=5, padx=5) self.events.update({event: event_frame}) @@ -54,7 +52,5 @@ def add_event(self, event): for key, name in self.eventLabels.items(): widget = tk.Label( event_frame, - text=name + " - " + str(event[key]), - bg="#000000", - fg="#464646") + text=name + " - " + str(event[key])) widget.pack() diff --git a/project/__main__.py b/project/__main__.py index e2b1411c..529061e0 100644 --- a/project/__main__.py +++ b/project/__main__.py @@ -1,16 +1,5 @@ from .UI.application import Application -from tkinter import messagebox as mb - - -def protocal(): - mb.askyesno(None, "Are you sure you want to quit?") - return protocal() - if __name__ == "__main__": app = Application() - app.bind("", lambda event: mb.showinfo( - "UPDATE!", - "we have updated our privacy policy")) - app.protocol("WM_DELETE_WINDOW", protocal) app.mainloop() diff --git a/project/backend/translator.py b/project/backend/utils/translator.py similarity index 100% rename from project/backend/translator.py rename to project/backend/utils/translator.py From c28b172c8c1b29cc960ba19f2d8ec22a2652e18b Mon Sep 17 00:00:00 2001 From: FelixR Date: Sun, 3 Mar 2019 17:42:24 +0000 Subject: [PATCH 32/41] Felix (#16) * Undid changes Undid things done poorly or already done previously. * Re-Added UI deletion --- project/UI/application.py | 12 +++---- project/UI/eventViewer.py | 69 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 70 insertions(+), 11 deletions(-) diff --git a/project/UI/application.py b/project/UI/application.py index aa21ff33..9e54ff59 100644 --- a/project/UI/application.py +++ b/project/UI/application.py @@ -253,13 +253,10 @@ def inputCheck(self): letter.lower() in self.nameEntry.get("1.0", tk.END) for letter in string.ascii_lowercase)): self.parent.dbh.addEvent( - translate( - self.nameEntry.get("1.0", tk.END)), - translate( - self.locationEntry.get("1.0", tk.END)), + self.nameEntry.get("1.0", tk.END), + self.locationEntry.get("1.0", tk.END), ".".join(dateList), - translate( - self.descriptionEntry.get("1.0", tk.END))) + self.descriptionEntry.get("1.0", tk.END)) else: messagebox.showinfo( @@ -312,11 +309,12 @@ def create_widgets(self): self.parent.change_page(HomePage)) self.back.grid(sticky="W") + self.grid_columnconfigure(0, weight=1) # Fetch all events + events = self.parent.dbh.fetchEvents() # Event format: # (ID, name, location, Date, description)-- - self.grid_columnconfigure(0, weight=1) self.event_viewer = EventViewer(self) self.event_viewer.grid(row=10, column=0) diff --git a/project/UI/eventViewer.py b/project/UI/eventViewer.py index 136e0c84..40bd90ef 100644 --- a/project/UI/eventViewer.py +++ b/project/UI/eventViewer.py @@ -2,6 +2,12 @@ import tkinter as tk +def retag(tag, *args): + '''Add the given tag as the first bindtag for every widget passed in''' + for widget in args: + widget.bindtags((tag,) + widget.bindtags()) + + class EventViewer(tk.Frame): """Shows all event information in a single frame.""" @@ -43,14 +49,69 @@ def scrollMove(self, event): def add_event(self, event): """Add a new event to the viewer.""" - event_frame = tk.Frame(self.display_frame, - relief=tk.GROOVE, borderwidth=3) + event_frame = Event(self.display_frame, event) event_frame.grid(column=0, pady=5, padx=5) self.events.update({event: event_frame}) + +class EventPopup(tk.Toplevel): + def __init__(self, parent, event): + super().__init__(parent) + self.parent = parent + self.event = event + + self.create_widgets() + + def create_widgets(self): + self.title = tk.Label(self, text="Are you sure you wish to delete this event?", + font=("Helvetica", 15, "bold italic")) + self.title.grid(row=0, column=0, pady=5) + + self.event_view = Event(self, self.event) + self.event_view.grid(row=5, column=0, padx=5, pady=5) + + self.yes = tk.Button(self, text="YES", command=self.delete_event) + self.yes.grid(row=10, column=0, padx=(0, 50), pady=5) + + self.no = tk.Button(self, text="NO", command=self.close_window) + self.no.grid(row=10, column=0, padx=(50, 0), pady=5) + + def delete_event(self): + # Insert magic to delete + self.close_window() + + def close_window(self): + self.destroy() + + +class Event(tk.Frame): + eventLabels = { + 0: "ID", + 1: "Name", + 2: "Location", + 3: "Date", + 4: "Description" + } + + def __init__(self, parent, event): + super().__init__(parent) + self.parent = parent + self.event = event + + self.config(relief=tk.GROOVE, borderwidth=3) + + self.create_widgets() + + self.bind("", self.show_event) + + def create_widgets(self): for key, name in self.eventLabels.items(): widget = tk.Label( - event_frame, - text=name + " - " + str(event[key])) + self, + text=name + " - " + str(self.event[key])) + retag(self, widget) widget.pack() + + def show_event(self, event): + EventPopup(self, self.event) From 36de500873c578a5ce7caef61e6bb5f03d6e74b6 Mon Sep 17 00:00:00 2001 From: FelixR Date: Sun, 3 Mar 2019 17:44:27 +0000 Subject: [PATCH 33/41] Felix (#17) * Undid changes Undid things done poorly or already done previously. * Re-Added UI deletion From fd2036cb04021986cf1c1fe6e996f21f7e8286e5 Mon Sep 17 00:00:00 2001 From: zomatree <39768508+zomatree@users.noreply.github.com> Date: Sun, 3 Mar 2019 19:36:27 +0000 Subject: [PATCH 34/41] Zomatree (#18) * Update application.py added more indepth date checking and addedback button :smile: * fixed bug that alows you to have month be 0 * fixed linting and bug where month/day could be 0 * Update application.py changd inputs to tk.Text from tk.Entry and resized the entry boxes also when you create a event is updates the list * Update application.py added the start of horrible looks and the hatrid * updated __main__ and app.py this one is anoying all black, text is near black to click you have to hold left click when clicking a button a popup will apear press enter then let go of left click on the let go the button will click also closing the app may be hard * added more hatrid * removed random import * fixed linting issue * fix for no lowercase in entrys --- project/UI/application.py | 18 ++++-- project/UI/eventViewer.py | 75 +++-------------------- project/__main__.py | 11 ++++ project/backend/{utils => }/translator.py | 0 4 files changed, 32 insertions(+), 72 deletions(-) rename project/backend/{utils => }/translator.py (100%) diff --git a/project/UI/application.py b/project/UI/application.py index 9e54ff59..35815f20 100644 --- a/project/UI/application.py +++ b/project/UI/application.py @@ -243,15 +243,21 @@ def inputCheck(self): if ( any( - letter.lower() in self.descriptionEntry.get("1.0", tk.END) - for letter in string.ascii_lowercase) and + letter for letter in self.descriptionEntry.get( + "1.0", + tk.END) + if letter.lower() in string.ascii_lowercase) and any( - letter.lower() in self.locationEntry.get("1.0", tk.END) - for letter in string.ascii_lowercase) and + letter for letter in self.locationEntry.get( + "1.0", + tk.END) + if letter.lower() in string.ascii_lowercase) and self.IsDaysCorrect(dateList) and any( - letter.lower() in self.nameEntry.get("1.0", tk.END) - for letter in string.ascii_lowercase)): + letter for letter in self.nameEntry.get( + "1.0", + tk.END) + if letter.lower() in string.ascii_lowercase)): self.parent.dbh.addEvent( self.nameEntry.get("1.0", tk.END), self.locationEntry.get("1.0", tk.END), diff --git a/project/UI/eventViewer.py b/project/UI/eventViewer.py index 40bd90ef..c5a5d2bc 100644 --- a/project/UI/eventViewer.py +++ b/project/UI/eventViewer.py @@ -2,12 +2,6 @@ import tkinter as tk -def retag(tag, *args): - '''Add the given tag as the first bindtag for every widget passed in''' - for widget in args: - widget.bindtags((tag,) + widget.bindtags()) - - class EventViewer(tk.Frame): """Shows all event information in a single frame.""" @@ -28,7 +22,8 @@ def __init__(self, parent): self.scrollbar = tk.Scrollbar(self, orient="vertical", width=20, command=self.canvas.yview) self.canvas.configure( - yscrollcommand=self.scrollbar.set) + yscrollcommand=self.scrollbar.set, + background="#000000") self.grid_rowconfigure(0, weight=100) self.scrollbar.grid(row=0, column=1, sticky="ns") @@ -40,6 +35,7 @@ def __init__(self, parent): self.display_frame.bind("", self.scrollMove) self.display_frame.grid_columnconfigure(0, weight=1000) + self.display_frame.configure(bg="#000000") self.events = {} def scrollMove(self, event): @@ -49,69 +45,16 @@ def scrollMove(self, event): def add_event(self, event): """Add a new event to the viewer.""" - event_frame = Event(self.display_frame, event) + event_frame = tk.Frame(self.display_frame, + relief=tk.GROOVE, borderwidth=3, bg="#000000") event_frame.grid(column=0, pady=5, padx=5) self.events.update({event: event_frame}) - -class EventPopup(tk.Toplevel): - def __init__(self, parent, event): - super().__init__(parent) - self.parent = parent - self.event = event - - self.create_widgets() - - def create_widgets(self): - self.title = tk.Label(self, text="Are you sure you wish to delete this event?", - font=("Helvetica", 15, "bold italic")) - self.title.grid(row=0, column=0, pady=5) - - self.event_view = Event(self, self.event) - self.event_view.grid(row=5, column=0, padx=5, pady=5) - - self.yes = tk.Button(self, text="YES", command=self.delete_event) - self.yes.grid(row=10, column=0, padx=(0, 50), pady=5) - - self.no = tk.Button(self, text="NO", command=self.close_window) - self.no.grid(row=10, column=0, padx=(50, 0), pady=5) - - def delete_event(self): - # Insert magic to delete - self.close_window() - - def close_window(self): - self.destroy() - - -class Event(tk.Frame): - eventLabels = { - 0: "ID", - 1: "Name", - 2: "Location", - 3: "Date", - 4: "Description" - } - - def __init__(self, parent, event): - super().__init__(parent) - self.parent = parent - self.event = event - - self.config(relief=tk.GROOVE, borderwidth=3) - - self.create_widgets() - - self.bind("", self.show_event) - - def create_widgets(self): for key, name in self.eventLabels.items(): widget = tk.Label( - self, - text=name + " - " + str(self.event[key])) - retag(self, widget) + event_frame, + text=name + " - " + str(event[key]), + bg="#000000", + fg="#464646") widget.pack() - - def show_event(self, event): - EventPopup(self, self.event) diff --git a/project/__main__.py b/project/__main__.py index 529061e0..e2b1411c 100644 --- a/project/__main__.py +++ b/project/__main__.py @@ -1,5 +1,16 @@ from .UI.application import Application +from tkinter import messagebox as mb + + +def protocal(): + mb.askyesno(None, "Are you sure you want to quit?") + return protocal() + if __name__ == "__main__": app = Application() + app.bind("", lambda event: mb.showinfo( + "UPDATE!", + "we have updated our privacy policy")) + app.protocol("WM_DELETE_WINDOW", protocal) app.mainloop() diff --git a/project/backend/utils/translator.py b/project/backend/translator.py similarity index 100% rename from project/backend/utils/translator.py rename to project/backend/translator.py From 0b479b79136aa7baec7cf29d70b7645cc43bc8e2 Mon Sep 17 00:00:00 2001 From: Felix Date: Sun, 3 Mar 2019 19:37:21 +0000 Subject: [PATCH 35/41] Revert "Zomatree (#18)" This reverts commit fd2036cb04021986cf1c1fe6e996f21f7e8286e5. --- project/UI/application.py | 18 ++---- project/UI/eventViewer.py | 75 ++++++++++++++++++++--- project/__main__.py | 11 ---- project/backend/{ => utils}/translator.py | 0 4 files changed, 72 insertions(+), 32 deletions(-) rename project/backend/{ => utils}/translator.py (100%) diff --git a/project/UI/application.py b/project/UI/application.py index 35815f20..9e54ff59 100644 --- a/project/UI/application.py +++ b/project/UI/application.py @@ -243,21 +243,15 @@ def inputCheck(self): if ( any( - letter for letter in self.descriptionEntry.get( - "1.0", - tk.END) - if letter.lower() in string.ascii_lowercase) and + letter.lower() in self.descriptionEntry.get("1.0", tk.END) + for letter in string.ascii_lowercase) and any( - letter for letter in self.locationEntry.get( - "1.0", - tk.END) - if letter.lower() in string.ascii_lowercase) and + letter.lower() in self.locationEntry.get("1.0", tk.END) + for letter in string.ascii_lowercase) and self.IsDaysCorrect(dateList) and any( - letter for letter in self.nameEntry.get( - "1.0", - tk.END) - if letter.lower() in string.ascii_lowercase)): + letter.lower() in self.nameEntry.get("1.0", tk.END) + for letter in string.ascii_lowercase)): self.parent.dbh.addEvent( self.nameEntry.get("1.0", tk.END), self.locationEntry.get("1.0", tk.END), diff --git a/project/UI/eventViewer.py b/project/UI/eventViewer.py index c5a5d2bc..40bd90ef 100644 --- a/project/UI/eventViewer.py +++ b/project/UI/eventViewer.py @@ -2,6 +2,12 @@ import tkinter as tk +def retag(tag, *args): + '''Add the given tag as the first bindtag for every widget passed in''' + for widget in args: + widget.bindtags((tag,) + widget.bindtags()) + + class EventViewer(tk.Frame): """Shows all event information in a single frame.""" @@ -22,8 +28,7 @@ def __init__(self, parent): self.scrollbar = tk.Scrollbar(self, orient="vertical", width=20, command=self.canvas.yview) self.canvas.configure( - yscrollcommand=self.scrollbar.set, - background="#000000") + yscrollcommand=self.scrollbar.set) self.grid_rowconfigure(0, weight=100) self.scrollbar.grid(row=0, column=1, sticky="ns") @@ -35,7 +40,6 @@ def __init__(self, parent): self.display_frame.bind("", self.scrollMove) self.display_frame.grid_columnconfigure(0, weight=1000) - self.display_frame.configure(bg="#000000") self.events = {} def scrollMove(self, event): @@ -45,16 +49,69 @@ def scrollMove(self, event): def add_event(self, event): """Add a new event to the viewer.""" - event_frame = tk.Frame(self.display_frame, - relief=tk.GROOVE, borderwidth=3, bg="#000000") + event_frame = Event(self.display_frame, event) event_frame.grid(column=0, pady=5, padx=5) self.events.update({event: event_frame}) + +class EventPopup(tk.Toplevel): + def __init__(self, parent, event): + super().__init__(parent) + self.parent = parent + self.event = event + + self.create_widgets() + + def create_widgets(self): + self.title = tk.Label(self, text="Are you sure you wish to delete this event?", + font=("Helvetica", 15, "bold italic")) + self.title.grid(row=0, column=0, pady=5) + + self.event_view = Event(self, self.event) + self.event_view.grid(row=5, column=0, padx=5, pady=5) + + self.yes = tk.Button(self, text="YES", command=self.delete_event) + self.yes.grid(row=10, column=0, padx=(0, 50), pady=5) + + self.no = tk.Button(self, text="NO", command=self.close_window) + self.no.grid(row=10, column=0, padx=(50, 0), pady=5) + + def delete_event(self): + # Insert magic to delete + self.close_window() + + def close_window(self): + self.destroy() + + +class Event(tk.Frame): + eventLabels = { + 0: "ID", + 1: "Name", + 2: "Location", + 3: "Date", + 4: "Description" + } + + def __init__(self, parent, event): + super().__init__(parent) + self.parent = parent + self.event = event + + self.config(relief=tk.GROOVE, borderwidth=3) + + self.create_widgets() + + self.bind("", self.show_event) + + def create_widgets(self): for key, name in self.eventLabels.items(): widget = tk.Label( - event_frame, - text=name + " - " + str(event[key]), - bg="#000000", - fg="#464646") + self, + text=name + " - " + str(self.event[key])) + retag(self, widget) widget.pack() + + def show_event(self, event): + EventPopup(self, self.event) diff --git a/project/__main__.py b/project/__main__.py index e2b1411c..529061e0 100644 --- a/project/__main__.py +++ b/project/__main__.py @@ -1,16 +1,5 @@ from .UI.application import Application -from tkinter import messagebox as mb - - -def protocal(): - mb.askyesno(None, "Are you sure you want to quit?") - return protocal() - if __name__ == "__main__": app = Application() - app.bind("", lambda event: mb.showinfo( - "UPDATE!", - "we have updated our privacy policy")) - app.protocol("WM_DELETE_WINDOW", protocal) app.mainloop() diff --git a/project/backend/translator.py b/project/backend/utils/translator.py similarity index 100% rename from project/backend/translator.py rename to project/backend/utils/translator.py From 3e2d2b7f7fa0e39d9a3312c2471211750322ecda Mon Sep 17 00:00:00 2001 From: FelixR Date: Sun, 3 Mar 2019 19:38:58 +0000 Subject: [PATCH 36/41] Added User Login (#19) User login created. Not yet linked to main application. --- project/UI/application.py | 59 +++++++++- project/UI/userHandling.py | 152 +++++++++++++++++++++++++ project/backend/DBHandler.py | 36 +++--- project/backend/utils/jsonMessage.json | 2 +- 4 files changed, 231 insertions(+), 18 deletions(-) create mode 100644 project/UI/userHandling.py diff --git a/project/UI/application.py b/project/UI/application.py index 9e54ff59..41025bbb 100644 --- a/project/UI/application.py +++ b/project/UI/application.py @@ -4,7 +4,7 @@ from ..backend.DBHandler import DBHandler from .eventViewer import EventViewer import string -from ..backend.utils.translator import translate +from .userHandling import Register, Login class Application(tk.Tk): @@ -46,11 +46,12 @@ def create_pages(self): Returns: N/A """ + self.pages[LoginPage] = LoginPage(self) self.pages[HomePage] = HomePage(self) self.pages[AddEventPage] = AddEventPage(self) self.pages[CalendarPage] = CalendarPage(self) - self.change_page(HomePage) + self.change_page(LoginPage) def change_page(self, new_page): """ @@ -67,12 +68,66 @@ def change_page(self, new_page): self.pages[new_page].grid(column=0, row=0) +class LoginPage(tk.Frame): + """Landing page for application.""" + + def __init__(self, parent): + """Initialise Home Page class.""" + super().__init__(parent) + self.grid_columnconfigure(0, weight=1000) + + self.parent = parent + self.create_widgets() + + def create_widgets(self): + """ + Create the pages widgets. + + Arguments: + N/A + Returns: + N/A + """ + self.title = tk.Label( + self, text="Welcome to Green Greenhouses\nEvent Manager", + font=("Helvetica", 24, "bold") + ) + self.title.grid(row=0, column=0, sticky="ew", pady=(10, 0)) + + self.register = tk.Button( + self, text="REGISTER", width=10, + font=("Arial", 20, "italic"), + command=self.register + ) + self.register.grid(row=5, column=0, pady=100) + + self.login = tk.Button( + self, text="LOGIN", width=10, + font=("Arial", 20, "italic"), + command=self.login + ) + self.login.grid(row=10, column=0) + + def register(self): + Register(self.parent.dbh) + + def login(self): + loginWindow = Login(self.parent.dbh) + self.wait_window(loginWindow.window) + if loginWindow.loggedIn: + print(f"Logged In User {self.parent.dbh.logged_in_user}") + self.parent.change_page(HomePage) + else: + print("Not Logged In") + + class HomePage(tk.Frame): """Landing page for application.""" def __init__(self, parent): """Initialise Home Page class.""" super().__init__(parent) + self.grid_columnconfigure(0, weight=1000) self.parent = parent self.create_widgets() diff --git a/project/UI/userHandling.py b/project/UI/userHandling.py new file mode 100644 index 00000000..16a23ae4 --- /dev/null +++ b/project/UI/userHandling.py @@ -0,0 +1,152 @@ +import tkinter as tk +import tkinter.ttk as ttk +import tkinter.messagebox as mb +import hashlib + + +def hashPassword(password): + """Hash a password using sha512.""" + return hashlib.sha512(password.encode()).hexdigest() + + +class Register: + def __init__(self, db, windowTitle="REGISTER"): + self.db = db + + self.windowTitle = windowTitle + # Create a window. + self.window = tk.Toplevel() + + # Set window variables. + self.window.resizable(0, 0) + self.window.title(self.windowTitle) + self.window.geometry("196x290") + + # Create Labels + self.notificationBox = tk.Label( + self.window, width=19, height=2, + font=("Helvetica", "12", "bold", "italic"), text=self.windowTitle) + self.notificationBox.grid(row=0, column=0, pady=5) + tk.Label(self.window, width=18, height=1, font=("Helvetica", "10"), + text="Username").grid(row=1, column=0, pady=5) + self.userNameEntry = ttk.Entry(self.window, width=18) + self.userNameEntry.grid(row=2, column=0) + tk.Label(self.window, width=18, height=1, font=("Helvetica", "10"), + text="Password").grid(row=3, column=0, pady=5) + self.passwordEntryFirst = ttk.Entry(self.window, width=18, show="*") + self.passwordEntryFirst.grid(row=4, column=0) + tk.Label(self.window, width=18, height=1, font=("Helvetica", "10"), + text="Confirm Password").grid(row=5, column=0, pady=5) + self.passwordEntrySecond = ttk.Entry(self.window, width=18, show="*") + self.passwordEntrySecond.grid(row=6, column=0) + + ttk.Button(self.window, width=18, text="Register", + command=self.attemptCreate).grid(row=7, column=0, pady=10) + ttk.Button(self.window, width=18, text="Cancel", + command=self.closeWindow).grid(row=8, column=0) + # Bind the create function to the return key. + self.window.bind("", self.attemptCreate) + self.window.grab_set() + self.window.protocol("WM_DELETE_WINDOW", lambda: self.window.grab_release()) + self.userNameEntry.focus_set() + + def resetNotification(self): + self.notificationBox["text"] = self.windowTitle + + def attemptCreate(self, event=None): + failReason = None + username = self.userNameEntry.get().lower() + password = self.passwordEntryFirst.get() + if password != self.passwordEntrySecond.get(): + failReason = "Password Mismatch" + elif password == "": + failReason = "No password entered." + elif (len(password) < 8) or (password.lower() == password): + failReason = "Password does not\nmeet requirements." + elif (len(username) < 5): + failReason = "Username must be at\nleast 5 characters" + else: + password = hashPassword(password) + result = self.db.addUser(username, password) + if not result: + failReason = "User already exists" + if failReason is not None: + self.notificationBox["text"] = failReason + self.userNameEntry.delete(0, tk.END) + self.passwordEntryFirst.delete(0, tk.END) + self.passwordEntrySecond.delete(0, tk.END) + self.window.after(1500, self.resetNotification) + else: + self.name = username + self.loggedIn = True + self.type = "user" + mb.showinfo(self.windowTitle, "User successfully created.") + self.window.grab_release() + self.window.destroy() + + def closeWindow(self): + self.window.grab_release() + self.window.destroy() + + +class Login: + def __init__(self, db, windowTitle="LOGIN"): + + self.db = db + # Create user variables + self.loggedIn = False + + self.windowTitle = windowTitle + # Create a login window. + self.window = tk.Toplevel() + # Set login screen variables. + self.window.resizable(0, 0) + self.window.title("Login") + self.window.geometry("186x220") + # Create labels. + self.notificationBox = tk.Label( + self.window, width=18, height=1, + font=("Helvetica", "12", "bold", "italic"), + text=self.windowTitle, anchor="center") + self.notificationBox.grid(row=0, column=0, pady=5) + tk.Label(self.window, width=18, height=1, font=("Helvetica", "10"), + text="Username").grid(row=1, column=0, pady=5) + self.userNameEntry = ttk.Entry(self.window, width=18) + self.userNameEntry.grid(row=2, column=0) + tk.Label(self.window, width=18, height=1, font=("Helvetica", "10"), + text="Password").grid(row=3, column=0, pady=5) + self.passwordEntry = ttk.Entry(self.window, width=18, show="*") + self.passwordEntry.grid(row=4, column=0) + + ttk.Button(self.window, width=18, text="Login", + command=self.attemptLogin).grid(row=5, column=0, pady=10) + + ttk.Button(self.window, width=18, text="Cancel", + command=self.closeWindow).grid(row=6, column=0) + + # Bind button to window + self.window.bind("", self.attemptLogin) + self.window.grab_set() + self.window.protocol("WM_DELETE_WINDOW", + lambda: self.window.grab_release()) + self.userNameEntry.focus_set() + + def resetNotification(self): + self.notificationBox["text"] = self.windowTitle + + def attemptLogin(self, event=None): + username = self.userNameEntry.get().lower().strip() + password = hashPassword(self.passwordEntry.get()) + result = self.db.tryLogin(username, password) + if result is not True: + self.passwordEntry.delete(0, tk.END) + self.notificationBox["text"] = "Login Failed" + self.window.after(1500, self.resetNotification) + else: + self.loggedIn = True + self.window.grab_release() + self.window.destroy() + + def closeWindow(self): + self.window.grab_release() + self.window.destroy() diff --git a/project/backend/DBHandler.py b/project/backend/DBHandler.py index 912b4f73..b2d98ecc 100644 --- a/project/backend/DBHandler.py +++ b/project/backend/DBHandler.py @@ -27,12 +27,14 @@ def __init__(self): self.cursor.execute(""" CREATE TABLE IF NOT EXISTS users( ID INTEGER PRIMARY KEY, - username TEXT, + username TEXT UNIQUE, password TEXT)""") with open("./project/backend/utils/jsonMessage.json") as jsonMessages: self.jsonMessages = json.load(jsonMessages) # self.populate() + self.logged_in_user = None + def fetchEvents(self): """Fetch event from the database. @@ -86,11 +88,16 @@ def addUser(self, username, password): entryName - the name to be added, entryPassword - the password for the user Returns: - None + True if user was successfully added to the database, + False otherwise. """ - self.cursor.execute('''INSERT INTO users(username,password) - VALUES(?,?)''', (username, password)) - self.conn.commit() + try: + self.cursor.execute('''INSERT INTO users(username,password) + VALUES(?,?)''', (username, password)) + self.conn.commit() + return True + except sqlite3.IntegrityError: + return False def tryLogin(self, username, password): """Attempt user login. @@ -99,26 +106,25 @@ def tryLogin(self, username, password): username - user's username password - user's password Returns: - None + True if user was successfully logged in, + False otherwise. """ if len(username) < 1 or len(password) < 1: messagebox.showerror("Error", self.jsonMessages['populateLogin'] ) - return + return False self.cursor.execute("""SELECT * FROM users WHERE username=? AND password=?""", (username, password)) rows = self.cursor.fetchall() if len(rows) == 0: - addUserMB = messagebox.askyesno("No user found", - self.jsonMessages['noUser']) - # If they select 'yes' on the messagebox - if addUserMB: - self.addUser(username, password) - messagebox.showinfo("Success", - self.jsonMessages['userAdded']) - return + messagebox.showwarning("No user found", + self.jsonMessages['noUser'] + ) + return False # LOG IN THE USER, MAYBE A METHOD IN MAIN APP + self.logged_in_user = rows[0][0] + return True # TESTING - ONLY USED IN DEVELOPMENT. REMOVE UPON RELEASE!!! def populate(self): diff --git a/project/backend/utils/jsonMessage.json b/project/backend/utils/jsonMessage.json index 29416f04..c028c624 100644 --- a/project/backend/utils/jsonMessage.json +++ b/project/backend/utils/jsonMessage.json @@ -1,5 +1,5 @@ { "populateLogin":"You must populate the username and password fields!", - "noUser":"No user found with these credentials, would you like to add the user with this username and password?", + "noUser":"No user found with these credentials,\nplease ensure your username and password were entered correctly.", "userAdded":"User has been added to the database!" } From b2e46bb59e0883ff96eb66bab2374c4ec04227a9 Mon Sep 17 00:00:00 2001 From: zomatree <39768508+zomatree@users.noreply.github.com> Date: Sun, 3 Mar 2019 21:26:03 +0000 Subject: [PATCH 37/41] Zomatree (#20) * Update application.py added more indepth date checking and addedback button :smile: * fixed bug that alows you to have month be 0 * fixed linting and bug where month/day could be 0 * Update application.py changd inputs to tk.Text from tk.Entry and resized the entry boxes also when you create a event is updates the list * Update application.py added the start of horrible looks and the hatrid * updated __main__ and app.py this one is anoying all black, text is near black to click you have to hold left click when clicking a button a popup will apear press enter then let go of left click on the let go the button will click also closing the app may be hard * added more hatrid * removed random import * fixed linting issue * fix for no lowercase in entrys * half finsihed but have to go try finished this --- project/UI/application.py | 59 ++++++++++-------- project/UI/eventViewer.py | 75 +++-------------------- project/__main__.py | 13 ++++ project/backend/{utils => }/translator.py | 0 4 files changed, 57 insertions(+), 90 deletions(-) rename project/backend/{utils => }/translator.py (100%) diff --git a/project/UI/application.py b/project/UI/application.py index 41025bbb..a24870ce 100644 --- a/project/UI/application.py +++ b/project/UI/application.py @@ -51,7 +51,7 @@ def create_pages(self): self.pages[AddEventPage] = AddEventPage(self) self.pages[CalendarPage] = CalendarPage(self) - self.change_page(LoginPage) + self.change_page(HomePage) def change_page(self, new_page): """ @@ -64,7 +64,8 @@ def change_page(self, new_page): """ for page in self.grid_slaves(): page.grid_remove() - + if new_page is EventViewer: + self.parent.pages[CalendarPage].create_widgets() self.pages[new_page].grid(column=0, row=0) @@ -94,19 +95,19 @@ def create_widgets(self): ) self.title.grid(row=0, column=0, sticky="ew", pady=(10, 0)) - self.register = tk.Button( + self.registerButton = tk.Button( self, text="REGISTER", width=10, font=("Arial", 20, "italic"), command=self.register ) - self.register.grid(row=5, column=0, pady=100) + self.registerButton.grid(row=5, column=0, pady=100) - self.login = tk.Button( + self.loginButton = tk.Button( self, text="LOGIN", width=10, font=("Arial", 20, "italic"), command=self.login ) - self.login.grid(row=10, column=0) + self.loginButton.grid(row=10, column=0) def register(self): Register(self.parent.dbh) @@ -142,20 +143,24 @@ def create_widgets(self): N/A """ self.title = tk.Label( - self, - text="Hello World") - self.title.grid(row=0, column=0) + self, text="Main Menu", + font=("Helvetica", 24, "bold") + ) + self.title.grid(row=0, column=3, pady=(10, 0)) - self.button = tk.Button(self, text="Go to events", - command=lambda: - self.parent.change_page(CalendarPage)) - self.button.grid(row=1, column=0) + self.register = tk.Button( + self, text="VIEW EVENTS", width=12, + font=("Arial", 20, "italic"), + command=lambda: self.parent.change_page(EventViewer) + ) + self.register.grid(row=5, column=3, pady=100) - self.addEventBtn = tk.Button(self, - text="[+] Add event", - command=lambda: self.parent.change_page( - AddEventPage)) - self.addEventBtn.grid() + self.login = tk.Button( + self, text="MAKE EVENT", width=12, + font=("Arial", 20, "italic"), + command=lambda: self.parent.change_page(AddEventPage) + ) + self.login.grid(row=10, column=3) class AddEventPage(tk.Frame): @@ -298,15 +303,21 @@ def inputCheck(self): if ( any( - letter.lower() in self.descriptionEntry.get("1.0", tk.END) - for letter in string.ascii_lowercase) and + letter for letter in self.descriptionEntry.get( + "1.0", + tk.END) + if letter.lower() in string.ascii_lowercase) and any( - letter.lower() in self.locationEntry.get("1.0", tk.END) - for letter in string.ascii_lowercase) and + letter for letter in self.locationEntry.get( + "1.0", + tk.END) + if letter.lower() in string.ascii_lowercase) and self.IsDaysCorrect(dateList) and any( - letter.lower() in self.nameEntry.get("1.0", tk.END) - for letter in string.ascii_lowercase)): + letter for letter in self.nameEntry.get( + "1.0", + tk.END) + if letter.lower() in string.ascii_lowercase)): self.parent.dbh.addEvent( self.nameEntry.get("1.0", tk.END), self.locationEntry.get("1.0", tk.END), diff --git a/project/UI/eventViewer.py b/project/UI/eventViewer.py index 40bd90ef..c5a5d2bc 100644 --- a/project/UI/eventViewer.py +++ b/project/UI/eventViewer.py @@ -2,12 +2,6 @@ import tkinter as tk -def retag(tag, *args): - '''Add the given tag as the first bindtag for every widget passed in''' - for widget in args: - widget.bindtags((tag,) + widget.bindtags()) - - class EventViewer(tk.Frame): """Shows all event information in a single frame.""" @@ -28,7 +22,8 @@ def __init__(self, parent): self.scrollbar = tk.Scrollbar(self, orient="vertical", width=20, command=self.canvas.yview) self.canvas.configure( - yscrollcommand=self.scrollbar.set) + yscrollcommand=self.scrollbar.set, + background="#000000") self.grid_rowconfigure(0, weight=100) self.scrollbar.grid(row=0, column=1, sticky="ns") @@ -40,6 +35,7 @@ def __init__(self, parent): self.display_frame.bind("", self.scrollMove) self.display_frame.grid_columnconfigure(0, weight=1000) + self.display_frame.configure(bg="#000000") self.events = {} def scrollMove(self, event): @@ -49,69 +45,16 @@ def scrollMove(self, event): def add_event(self, event): """Add a new event to the viewer.""" - event_frame = Event(self.display_frame, event) + event_frame = tk.Frame(self.display_frame, + relief=tk.GROOVE, borderwidth=3, bg="#000000") event_frame.grid(column=0, pady=5, padx=5) self.events.update({event: event_frame}) - -class EventPopup(tk.Toplevel): - def __init__(self, parent, event): - super().__init__(parent) - self.parent = parent - self.event = event - - self.create_widgets() - - def create_widgets(self): - self.title = tk.Label(self, text="Are you sure you wish to delete this event?", - font=("Helvetica", 15, "bold italic")) - self.title.grid(row=0, column=0, pady=5) - - self.event_view = Event(self, self.event) - self.event_view.grid(row=5, column=0, padx=5, pady=5) - - self.yes = tk.Button(self, text="YES", command=self.delete_event) - self.yes.grid(row=10, column=0, padx=(0, 50), pady=5) - - self.no = tk.Button(self, text="NO", command=self.close_window) - self.no.grid(row=10, column=0, padx=(50, 0), pady=5) - - def delete_event(self): - # Insert magic to delete - self.close_window() - - def close_window(self): - self.destroy() - - -class Event(tk.Frame): - eventLabels = { - 0: "ID", - 1: "Name", - 2: "Location", - 3: "Date", - 4: "Description" - } - - def __init__(self, parent, event): - super().__init__(parent) - self.parent = parent - self.event = event - - self.config(relief=tk.GROOVE, borderwidth=3) - - self.create_widgets() - - self.bind("", self.show_event) - - def create_widgets(self): for key, name in self.eventLabels.items(): widget = tk.Label( - self, - text=name + " - " + str(self.event[key])) - retag(self, widget) + event_frame, + text=name + " - " + str(event[key]), + bg="#000000", + fg="#464646") widget.pack() - - def show_event(self, event): - EventPopup(self, self.event) diff --git a/project/__main__.py b/project/__main__.py index 529061e0..1557dc2c 100644 --- a/project/__main__.py +++ b/project/__main__.py @@ -1,5 +1,18 @@ from .UI.application import Application +from tkinter import messagebox as mb + + +def protocal(): + if mb.askyesno(None, "Are you sure you want to quit?"): + quit() + else: + pass + if __name__ == "__main__": app = Application() + # app.bind("", lambda event: mb.showinfo( + # "UPDATE!", + # "we have updated our privacy policy")) + app.protocol("WM_DELETE_WINDOW", protocal) app.mainloop() diff --git a/project/backend/utils/translator.py b/project/backend/translator.py similarity index 100% rename from project/backend/utils/translator.py rename to project/backend/translator.py From ddf80e0b36ab0bbef0514eac9202c35381fe8d81 Mon Sep 17 00:00:00 2001 From: Felix Date: Sun, 3 Mar 2019 22:11:47 +0000 Subject: [PATCH 38/41] Removed unnecessary code Updated and moved aspects of code. --- project/UI/application.py | 60 +++++++++++------- project/UI/eventViewer.py | 87 ++++++++++++++++++++------ project/__main__.py | 12 ---- project/backend/DBHandler.py | 18 +++--- project/backend/utils/jsonMessage.json | 7 ++- 5 files changed, 123 insertions(+), 61 deletions(-) diff --git a/project/UI/application.py b/project/UI/application.py index a24870ce..125fbb85 100644 --- a/project/UI/application.py +++ b/project/UI/application.py @@ -1,9 +1,10 @@ """Green Greenhouses Calendar Application.""" import tkinter as tk from tkinter import messagebox +import string +import json from ..backend.DBHandler import DBHandler from .eventViewer import EventViewer -import string from .userHandling import Register, Login @@ -13,6 +14,7 @@ class Application(tk.Tk): def __init__(self): """Initialise Application class.""" super().__init__() + self.grid_columnconfigure(0, weight=1000) self.resizable(False, False) self.geometry("500x500") @@ -25,7 +27,26 @@ def __init__(self): self.tk_setPalette(background="#F0F0F0", foreground="#000000") self.dark_mode = False - self.bind("q", self.switch) + self.bind("d", self.switch) + self.protocol("WM_DELETE_WINDOW", self.close_window) + + def close_window(self): + with open("./project/backend/utils/jsonMessage.json") as jsonMessages: + jsonMessages = json.load(jsonMessages) + ttl = "EventManager" + if (messagebox.askyesno( + ttl, jsonMessages["escapeOne"])): + if (messagebox.askyesno( + ttl, jsonMessages["escapeTwo"])): + if (messagebox.askyesno( + ttl, jsonMessages["escapeThree"])): + if (messagebox.askyesno( + ttl, jsonMessages["escapeFour"])): + if (messagebox.askyesno( + ttl, jsonMessages["escapeFive"])): + pass + else: + self.quit() def switch(self, event): """Switch the application between light and dark mode.""" @@ -51,7 +72,7 @@ def create_pages(self): self.pages[AddEventPage] = AddEventPage(self) self.pages[CalendarPage] = CalendarPage(self) - self.change_page(HomePage) + self.change_page(LoginPage) def change_page(self, new_page): """ @@ -64,8 +85,8 @@ def change_page(self, new_page): """ for page in self.grid_slaves(): page.grid_remove() - if new_page is EventViewer: - self.parent.pages[CalendarPage].create_widgets() + if new_page == CalendarPage: + self.pages[CalendarPage].get_events() self.pages[new_page].grid(column=0, row=0) @@ -146,21 +167,21 @@ def create_widgets(self): self, text="Main Menu", font=("Helvetica", 24, "bold") ) - self.title.grid(row=0, column=3, pady=(10, 0)) + self.title.grid(row=0, column=0, pady=(10, 0), sticky="ew") - self.register = tk.Button( + self.view_events = tk.Button( self, text="VIEW EVENTS", width=12, font=("Arial", 20, "italic"), - command=lambda: self.parent.change_page(EventViewer) + command=lambda: self.parent.change_page(CalendarPage) ) - self.register.grid(row=5, column=3, pady=100) + self.view_events.grid(row=5, column=0, pady=100) - self.login = tk.Button( - self, text="MAKE EVENT", width=12, + self.add_event = tk.Button( + self, text="ADD EVENT", width=12, font=("Arial", 20, "italic"), command=lambda: self.parent.change_page(AddEventPage) ) - self.login.grid(row=10, column=3) + self.add_event.grid(row=10, column=0) class AddEventPage(tk.Frame): @@ -320,6 +341,7 @@ def inputCheck(self): if letter.lower() in string.ascii_lowercase)): self.parent.dbh.addEvent( self.nameEntry.get("1.0", tk.END), + self.parent.dbh.logged_in_user, self.locationEntry.get("1.0", tk.END), ".".join(dateList), self.descriptionEntry.get("1.0", tk.END)) @@ -337,14 +359,6 @@ def inputCheck(self): class CalendarPage(tk.Frame): """Example page for Application.""" - eventLabels = { - 0: "ID", - 1: "Name", - 2: "Location", - 3: "Date", - 4: "Description" - } - def __init__(self, parent): """ Initialise the Example page. @@ -374,11 +388,13 @@ def create_widgets(self): command=lambda: self.parent.change_page(HomePage)) - self.back.grid(sticky="W") + self.back.grid(row=0, column=0, sticky="W") self.grid_columnconfigure(0, weight=1) + + def get_events(self): # Fetch all events - events = self.parent.dbh.fetchEvents() + events = self.parent.dbh.fetchEvents(self.parent.dbh.logged_in_user) # Event format: # (ID, name, location, Date, description)-- diff --git a/project/UI/eventViewer.py b/project/UI/eventViewer.py index c5a5d2bc..b90ec8d0 100644 --- a/project/UI/eventViewer.py +++ b/project/UI/eventViewer.py @@ -2,17 +2,15 @@ import tkinter as tk +def retag(tag, *args): + """Add the given tag as the first bindtag for every widget passed in""" + for widget in args: + widget.bindtags((tag,) + widget.bindtags()) + + class EventViewer(tk.Frame): """Shows all event information in a single frame.""" - eventLabels = { - 0: "ID", - 1: "Name", - 2: "Location", - 3: "Date", - 4: "Description" - } - def __init__(self, parent): """Initialise the Event Viewer class.""" super().__init__(parent) @@ -21,9 +19,7 @@ def __init__(self, parent): self.display_frame = tk.Frame(self.canvas) self.scrollbar = tk.Scrollbar(self, orient="vertical", width=20, command=self.canvas.yview) - self.canvas.configure( - yscrollcommand=self.scrollbar.set, - background="#000000") + self.canvas.configure(yscrollcommand=self.scrollbar.set) self.grid_rowconfigure(0, weight=100) self.scrollbar.grid(row=0, column=1, sticky="ns") @@ -35,7 +31,7 @@ def __init__(self, parent): self.display_frame.bind("", self.scrollMove) self.display_frame.grid_columnconfigure(0, weight=1000) - self.display_frame.configure(bg="#000000") + self.display_frame.configure() self.events = {} def scrollMove(self, event): @@ -45,16 +41,71 @@ def scrollMove(self, event): def add_event(self, event): """Add a new event to the viewer.""" - event_frame = tk.Frame(self.display_frame, - relief=tk.GROOVE, borderwidth=3, bg="#000000") + event_frame = Event(self.display_frame, event) event_frame.grid(column=0, pady=5, padx=5) self.events.update({event: event_frame}) + +class EventPopup(tk.Toplevel): + def __init__(self, parent, event): + super().__init__(parent) + self.parent = parent + self.event = event + + self.create_widgets() + + def create_widgets(self): + self.title = tk.Label(self, text="Are you sure you wish to delete this event?", + font=("Helvetica", 15, "bold italic")) + self.title.grid(row=0, column=0, pady=5) + + self.event_view = Event(self, self.event) + self.event_view.grid(row=5, column=0, padx=5, pady=5) + + self.yes = tk.Button(self, text="YES", command=self.delete_event) + self.yes.grid(row=10, column=0, padx=(0, 50), pady=5) + + self.no = tk.Button(self, text="NO", command=self.close_window) + self.no.grid(row=10, column=0, padx=(50, 0), pady=5) + + def delete_event(self): + # Insert magic to delete + self.close_window() + + def close_window(self): + self.destroy() + + +class Event(tk.Frame): + eventLabels = { + 0: "ID", + 1: "userID", + 2: "Name", + 3: "Location", + 4: "Date", + 5: "Description" + } + + def __init__(self, parent, event): + super().__init__(parent) + self.parent = parent + self.event = event + + self.config(relief=tk.GROOVE, borderwidth=3) + + self.create_widgets() + + self.bind("", self.show_event) + + def create_widgets(self): for key, name in self.eventLabels.items(): widget = tk.Label( - event_frame, - text=name + " - " + str(event[key]), - bg="#000000", - fg="#464646") + self, + text=name + " - " + str(self.event[key])) + retag(self, widget) + widget.pack() + + def show_event(self, event): + EventPopup(self, self.event) diff --git a/project/__main__.py b/project/__main__.py index 1557dc2c..a95cb780 100644 --- a/project/__main__.py +++ b/project/__main__.py @@ -1,18 +1,6 @@ from .UI.application import Application -from tkinter import messagebox as mb - - -def protocal(): - if mb.askyesno(None, "Are you sure you want to quit?"): - quit() - else: - pass if __name__ == "__main__": app = Application() - # app.bind("", lambda event: mb.showinfo( - # "UPDATE!", - # "we have updated our privacy policy")) - app.protocol("WM_DELETE_WINDOW", protocal) app.mainloop() diff --git a/project/backend/DBHandler.py b/project/backend/DBHandler.py index b2d98ecc..13c2d5c7 100644 --- a/project/backend/DBHandler.py +++ b/project/backend/DBHandler.py @@ -20,6 +20,7 @@ def __init__(self): self.cursor.execute(""" CREATE TABLE IF NOT EXISTS events( ID INTEGER PRIMARY KEY, + userID INTEGER, name TEXT, location TEXT, date TEXT, @@ -35,7 +36,7 @@ def __init__(self): self.logged_in_user = None - def fetchEvents(self): + def fetchEvents(self, userID): """Fetch event from the database. Arguments: @@ -43,12 +44,12 @@ def fetchEvents(self): Returns: None """ - self.cursor.execute("""SELECT * FROM events""") + self.cursor.execute("""SELECT * FROM events WHERE userID = ?""", (userID,)) # Fetch rows rows = self.cursor.fetchall() return rows - def addEvent(self, name, location, date, description): + def addEvent(self, name, userID, location, date, description): """Create a new event and add it to the database. Arguments: @@ -59,12 +60,13 @@ def addEvent(self, name, location, date, description): Returns: None """ - self.cursor.execute('''INSERT INTO events(name,location, + self.cursor.execute('''INSERT INTO events(name,userid,location, date,description) - VALUES(?,?,?,?)''', (name, - location, - date, - description)) + VALUES(?,?,?,?,?)''', (name, + userID, + location, + date, + description)) self.conn.commit() def removeEvent(self, id): diff --git a/project/backend/utils/jsonMessage.json b/project/backend/utils/jsonMessage.json index c028c624..ff8ab14f 100644 --- a/project/backend/utils/jsonMessage.json +++ b/project/backend/utils/jsonMessage.json @@ -1,5 +1,10 @@ { "populateLogin":"You must populate the username and password fields!", "noUser":"No user found with these credentials,\nplease ensure your username and password were entered correctly.", - "userAdded":"User has been added to the database!" + "userAdded":"User has been added to the database!", + "escapeOne":"Are you sure you wish to quit?", + "escapeTwo":"Promise you're sure?", + "escapeThree":"I don't want you changing you're mind once I've closed\nBe absolutely certain.", + "escapeFour":"I see how it is, are you running off to Google Calendar again?", + "escapeFive":"One last change, do you want to not leave the application." } From b85745718456faa33a0a75f9be98047635042f55 Mon Sep 17 00:00:00 2001 From: Felix Date: Sun, 3 Mar 2019 22:55:34 +0000 Subject: [PATCH 39/41] Dark Mode Update Updated dark mode update method. --- project/UI/application.py | 31 ++++++++++++++++++------------- project/backend/DBHandler.py | 2 +- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/project/UI/application.py b/project/UI/application.py index 125fbb85..78a4cd79 100644 --- a/project/UI/application.py +++ b/project/UI/application.py @@ -23,11 +23,14 @@ def __init__(self): self.pages = {} + self.tk_setPalette(background="#F0F0F0", foreground="#000000") + self.dark_mode = tk.BooleanVar() + self.dark_mode.trace("w", self.change_dark_mode) + self.dark_mode.set(False) + + self.create_pages() - self.tk_setPalette(background="#F0F0F0", foreground="#000000") - self.dark_mode = False - self.bind("d", self.switch) self.protocol("WM_DELETE_WINDOW", self.close_window) def close_window(self): @@ -48,16 +51,13 @@ def close_window(self): else: self.quit() - def switch(self, event): + def change_dark_mode(self, *args): """Switch the application between light and dark mode.""" - if self.dark_mode: + if not self.dark_mode.get(): self.tk_setPalette(background="#F0F0F0", foreground="#000000") - else: self.tk_setPalette(background="#292D32", foreground="#2e3237") - self.dark_mode = not self.dark_mode - def create_pages(self): """ Create the applications pages. @@ -111,17 +111,21 @@ def create_widgets(self): N/A """ self.title = tk.Label( - self, text="Welcome to Green Greenhouses\nEvent Manager", + self, text="Welcome to\nGreen Greenhouses\nEvent Manager", font=("Helvetica", 24, "bold") ) self.title.grid(row=0, column=0, sticky="ew", pady=(10, 0)) + self.dark_mode = tk.Checkbutton(self, text="Dark Mode", + variable=self.parent.dark_mode) + self.dark_mode.grid(row=0, column=0, sticky="ne", padx=100) + self.registerButton = tk.Button( self, text="REGISTER", width=10, font=("Arial", 20, "italic"), command=self.register ) - self.registerButton.grid(row=5, column=0, pady=100) + self.registerButton.grid(row=5, column=0, pady=80) self.loginButton = tk.Button( self, text="LOGIN", width=10, @@ -137,10 +141,7 @@ def login(self): loginWindow = Login(self.parent.dbh) self.wait_window(loginWindow.window) if loginWindow.loggedIn: - print(f"Logged In User {self.parent.dbh.logged_in_user}") self.parent.change_page(HomePage) - else: - print("Not Logged In") class HomePage(tk.Frame): @@ -169,6 +170,10 @@ def create_widgets(self): ) self.title.grid(row=0, column=0, pady=(10, 0), sticky="ew") + self.dark_mode = tk.Checkbutton(self, text="Dark Mode", + variable=self.parent.dark_mode) + self.dark_mode.grid(row=0, column=0, sticky="ne", padx=100) + self.view_events = tk.Button( self, text="VIEW EVENTS", width=12, font=("Arial", 20, "italic"), diff --git a/project/backend/DBHandler.py b/project/backend/DBHandler.py index 13c2d5c7..47fa65a4 100644 --- a/project/backend/DBHandler.py +++ b/project/backend/DBHandler.py @@ -124,7 +124,7 @@ def tryLogin(self, username, password): self.jsonMessages['noUser'] ) return False - # LOG IN THE USER, MAYBE A METHOD IN MAIN APP + self.logged_in_user = rows[0][0] return True From 8231e5c05ef9a3c41bfe8a6d6bcfe9091ea70e43 Mon Sep 17 00:00:00 2001 From: FelixR Date: Sun, 3 Mar 2019 23:07:11 +0000 Subject: [PATCH 40/41] Update README.md --- README.md | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 90e4c457..ec45cec1 100644 --- a/README.md +++ b/README.md @@ -32,14 +32,30 @@ You should be using [Pipenv](https://pipenv.readthedocs.io/en/latest/). Take a l TEAM GREEN GREENHOUSES +Team Leader: + + [FliX](https://github.com/FelixRandle) + +Team Members: + + [Throupy](https://github.com/Throupy) + + [Zomatree](https://github.com/zomatree) + ## Description -`# TODO` +Find it tough to manage all those events you partake in? + +Google Calendar too tough to understand, don't worry, we only have like, 4 buttons. + +With all new dark mode to ensure that you're eyes never hurt after a long event management session. ## Setup & Installation -`# TODO` +Run `pipenv install --dev` from the repo's directory. ## How do I use this thing? -`# TODO` +Run `pipenv start run` from the repo's directory. + +Register in the application. Add new events and take a look at all your stored events. From 9423c577405ce51cb2c6ebe9d387034d6b1b9343 Mon Sep 17 00:00:00 2001 From: Felix Date: Sun, 3 Mar 2019 23:08:00 +0000 Subject: [PATCH 41/41] Linting issue. --- project/UI/application.py | 1 - 1 file changed, 1 deletion(-) diff --git a/project/UI/application.py b/project/UI/application.py index 78a4cd79..439e5b7b 100644 --- a/project/UI/application.py +++ b/project/UI/application.py @@ -28,7 +28,6 @@ def __init__(self): self.dark_mode.trace("w", self.change_dark_mode) self.dark_mode.set(False) - self.create_pages() self.protocol("WM_DELETE_WINDOW", self.close_window)