├── requirements.txt ├── gallery ├── TD_SignIn.gif ├── Task_Diary.gif └── taskDiaryLogo.jpg ├── __pycache__ ├── auth.cpython-38.pyc ├── db.cpython-38.pyc ├── start.cpython-38.pyc └── task_diary_main.cpython-38.pyc ├── start.py ├── README.md ├── auth.py ├── db.py └── task_diary_main.py /requirements.txt: -------------------------------------------------------------------------------- 1 | tkcalender 2 | ttkthemes 3 | smtplib -------------------------------------------------------------------------------- /gallery/TD_SignIn.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/Task-diary/HEAD/gallery/TD_SignIn.gif -------------------------------------------------------------------------------- /gallery/Task_Diary.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/Task-diary/HEAD/gallery/Task_Diary.gif -------------------------------------------------------------------------------- /gallery/taskDiaryLogo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/Task-diary/HEAD/gallery/taskDiaryLogo.jpg -------------------------------------------------------------------------------- /__pycache__/auth.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/Task-diary/HEAD/__pycache__/auth.cpython-38.pyc -------------------------------------------------------------------------------- /__pycache__/db.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/Task-diary/HEAD/__pycache__/db.cpython-38.pyc -------------------------------------------------------------------------------- /__pycache__/start.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/Task-diary/HEAD/__pycache__/start.cpython-38.pyc -------------------------------------------------------------------------------- /__pycache__/task_diary_main.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/Task-diary/HEAD/__pycache__/task_diary_main.cpython-38.pyc -------------------------------------------------------------------------------- /start.py: -------------------------------------------------------------------------------- 1 | from tkinter import * 2 | from tkinter import simpledialog 3 | import db 4 | 5 | #Sign in to task-diary 6 | if __name__=='__main__': 7 | password_root = Tk() 8 | password_root.withdraw() 9 | password = simpledialog.askstring("Password", "Enter your PostgreSQL password:",show="*") 10 | password_root.destroy() 11 | 12 | if password is None: 13 | sys.exit() 14 | db.initialize_db(password) 15 | 16 | 17 | db.create_table5() 18 | import auth 19 | 20 | if(auth.signin==1): 21 | global username 22 | username=auth.f_username 23 | import task_diary_main 24 | 25 | 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | 4 |

5 |

Task Diary

6 | 7 |
8 | 9 | [![](https://img.shields.io/badge/Made_with-Python3-blue?style=for-the-badge&logo=python)](https://www.python.org "Python3") 10 | [![](https://img.shields.io/badge/Made_with-Postgresql-red?style=for-the-badge&logo=Postgresql)](https://www.postgresql.org/) 11 | 12 |

13 | 14 | ## Description ## 15 | 16 | Task Diary is a desktop application that enables user to keep all tasks in one application.User can filter the tasks and get notification of tasks. 17 |

18 | For more details- 19 | 20 | Document link 21 | 22 |

23 | 24 | ------------------------------------------ 25 | ## Features ## 26 | 27 | - User Sign In and Sign Up 28 | - Display tasks 29 | - Can add task,update task,delete task 30 | - Sort the tasks according to it's category,task name,due date and priority 31 | - Can browse the task 32 | - Get email,desktop notification 33 | - Overview of due dates in the form of calendar 34 | - Can Change theme 35 | ------------------------------------------ 36 | ## Demo ## 37 | Sign In 38 | 39 | ![Demo Sign In](gallery/TD_SignIn.gif) 40 | 41 | Task Diary 42 | 43 | ![Demo Task Diary](gallery/Task_Diary.gif) 44 | ## How To Use 45 | #### Software Requirements 46 | 47 | PostgreSql
48 | Python3 49 | 50 | #### Installation 51 | Install the dependencies by running: 52 | 53 | ```html 54 | pip install tkcalender 55 | pip install ttkthemes 56 | pip install smtplib 57 | ``` 58 | 59 | #### Run using Command Prompt 60 | 61 | ```html 62 | python start.py 63 | ``` 64 | #### For getting email notification of task: 65 | 66 | Allow less secure app access by clicking on Turn On : 67 | https://myaccount.google.com/lesssecureapps 68 | 69 | 70 | --- 71 | ### Tech stack 72 | `Backend` : Python3
73 | `Database` : PostgreSQL
74 | `Frontend` : Tkinter(module of python)
75 | 76 | 77 | ------------------------------------------ 78 | 79 |

Developed with :heart: by Hiral and Sakshi

80 | -------------------------------------------------------------------------------- /auth.py: -------------------------------------------------------------------------------- 1 | from tkinter import * 2 | import os 3 | from ttkthemes import themed_tk as ttkt 4 | from tkinter import messagebox 5 | import db 6 | 7 | def SignUp(): 8 | global SignUp_screen 9 | SignUp_screen = Toplevel(main_root) 10 | SignUp_screen.title("SignUp") 11 | SignUp_screen.geometry("300x250") 12 | 13 | global username 14 | global password 15 | global username_entry 16 | global password_entry 17 | username = StringVar() 18 | password = StringVar() 19 | 20 | Label(SignUp_screen, text="Please enter details below", bg="light steel blue").pack() 21 | Label(SignUp_screen, text="").pack() 22 | username_label = Label(SignUp_screen, text="Username * ") 23 | username_label.pack() 24 | username_entry = Entry(SignUp_screen, textvariable=username) 25 | username_entry.pack() 26 | password_label = Label(SignUp_screen, text="Password * ") 27 | password_label.pack() 28 | password_entry = Entry(SignUp_screen, textvariable=password) 29 | password_entry.pack() 30 | Label(SignUp_screen, text="").pack() 31 | Button(SignUp_screen, text="SignUp", width=10, height=1, bg="light steel blue", command = SignUp_user).pack() 32 | 33 | signin=0 34 | def SignIn(): 35 | global SignIn_screen 36 | SignIn_screen = Toplevel(main_root) 37 | SignIn_screen.title("SignIn") 38 | SignIn_screen.geometry("300x250") 39 | Label(SignIn_screen, text="Please enter details below to SignIn").pack() 40 | Label(SignIn_screen, text="").pack() 41 | 42 | global username_verify 43 | global password_verify 44 | 45 | username_verify = StringVar() 46 | password_verify = StringVar() 47 | 48 | global username_SignIn_entry 49 | global password_SignIn_entry 50 | 51 | Label(SignIn_screen, text="Username * ").pack() 52 | username_SignIn_entry = Entry(SignIn_screen, textvariable=username_verify) 53 | username_SignIn_entry.pack() 54 | Label(SignIn_screen, text="").pack() 55 | Label(SignIn_screen, text="Password * ").pack() 56 | password_SignIn_entry = Entry(SignIn_screen, textvariable=password_verify) 57 | password_SignIn_entry.pack() 58 | Label(SignIn_screen, text="").pack() 59 | Button(SignIn_screen, text="SignIn", width=10, height=1, command = SignIn_verify).pack() 60 | 61 | def SignUp_user(): 62 | username_value = username.get() 63 | occur=0 64 | for i in db.get_users():# i represents element of info which is list itself 65 | if username_value==i[0]:#to access the username of the "i" list and compare with the username entered by user 66 | occur=1 # if username already exists in database 67 | if occur==1: 68 | messagebox.showerror('Username',"User already exists") 69 | SignUp_screen.destroy() 70 | else: 71 | if(len(username_value)>=4 and len(username_value)<=10): 72 | password_value = password.get()#input password if username doesn't already exists 73 | length=len(password_value)# taking the length of password 74 | if length>=5 and length<=10:#To check all the conditions on the password are satisfied 75 | t=(username_value,password_value)#create a tuple "t" containing name and password 76 | db.add_user(t)# add to database 77 | messagebox.showinfo('SignUp',"Registration successful!") 78 | SignUp_screen.destroy() 79 | else: 80 | if(length<5 or length>10): 81 | messagebox.showerror('Password',"Your password should have 5-10 characters") 82 | else: 83 | if(len(username_value)<4 or len(username_value)>10): 84 | messagebox.showerror('Username',"Username should be 5-10 characters") 85 | # username_entry.delete(0, END) 86 | # password_entry.delete(0, END) 87 | 88 | 89 | def SignIn_verify(): 90 | 91 | username_value1 = username_verify.get() 92 | password_value1=password_verify.get() 93 | log=0#to check the sign-in success 94 | for g in db.get_users(): 95 | if g[0]==username_value1:#comparing the name 96 | if g[1]==password_value1:#if name is present comparing the name 97 | # messagebox.showinfo('Login','Logged in successfully!') 98 | print('Logged in successfully!') 99 | log=1#sign-in successful 100 | global signin 101 | global f_username 102 | signin=1 103 | f_username=username_value1 104 | SignIn_screen.destroy() 105 | main_root.destroy() 106 | else: 107 | messagebox.showerror('Login','Password incorrect!Try again') 108 | log=1 109 | SignIn_screen.destroy() 110 | if log==0: 111 | messagebox.showerror('Login','Failed to SignIn') 112 | SignIn_screen.destroy() 113 | 114 | def main_frame_screen(): 115 | global main_root 116 | main_root = ttkt.ThemedTk() 117 | main_root.set_theme('radiance') 118 | main_root.geometry("300x250") 119 | main_root.title("Account SignIn") 120 | Label(text="Select Your Choice", bg="light steel blue", width="300", height="2", font=("Comic Sans MS", 13)).pack() 121 | Label(text="").pack() 122 | Button(text="SignIn", height="2", width="30", command = SignIn).pack() 123 | Label(text="").pack() 124 | Button(text="SignUp", height="2", width="30", command=SignUp).pack() 125 | main_root.mainloop() 126 | 127 | main_frame_screen() -------------------------------------------------------------------------------- /db.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import psycopg2 3 | from tkinter import messagebox 4 | conn = None 5 | 6 | def initialize_db(password): 7 | """Initialize db connection with provided user password.""" 8 | print('Starting...') 9 | global conn 10 | 11 | try: 12 | conn = psycopg2.connect(database="postgres",#default databse in postgreSQL 13 | user="postgres",#username of postgreSQL 14 | password=password,#password of that user in postgreSQL 15 | host="127.0.0.1", 16 | port="5432") 17 | except psycopg2.OperationalError as exception: 18 | messagebox.showerror("password","PASSWORD IS INCORRECT. TRY AGAIN...") 19 | sys.exit() 20 | 21 | 22 | def create_table(): 23 | global conn 24 | try: 25 | #Creating a cursor object using the cursor() method 26 | cursor = conn.cursor() 27 | #Creating table tasks if it not exists... 28 | sql ='''CREATE TABLE IF NOT EXISTS TASKS( 29 | id int GENERATED ALWAYS AS IDENTITY primary key, 30 | task_name text, 31 | priority_of_task text, 32 | category text, 33 | is_done text, 34 | deadline text, 35 | username text 36 | )''' 37 | cursor.execute(sql) 38 | conn.commit() 39 | print("Table Tasks loaded successfully........") 40 | 41 | #Closing the connection 42 | except: 43 | print("Table Tasks is not loaded...") 44 | conn.close() 45 | 46 | def create_table2(): 47 | global conn 48 | try: 49 | #Creating table tasks if it not exists... 50 | cursor = conn.cursor() 51 | sql='''CREATE TABLE IF NOT EXISTS notification_tracker 52 | ( 53 | id int, 54 | notify_date text, 55 | username text 56 | ) ''' 57 | cursor.execute(sql) 58 | conn.commit() 59 | print("Table notification_tracker loaded successfully........") 60 | #Closing the connection 61 | except: 62 | print("Table notification_tracker is not loaded...") 63 | conn.close() 64 | 65 | def create_table3(): 66 | global conn 67 | try: 68 | #Creating table notify_email if it not exists... 69 | cursor = conn.cursor() 70 | sql='''CREATE TABLE IF NOT EXISTS notification_email 71 | ( 72 | id int GENERATED ALWAYS AS IDENTITY primary key, 73 | from_email text, 74 | password VARCHAR(30), 75 | to_email text, 76 | time text, 77 | username text 78 | ) ''' 79 | cursor.execute(sql) 80 | conn.commit() 81 | print("Table notification_email loaded successfully........") 82 | #Closing the connection 83 | except: 84 | print("Table notification_email is not loaded...") 85 | conn.close() 86 | 87 | def create_table4(): 88 | global conn 89 | try: 90 | #Creating table theme if it not exists... 91 | cursor = conn.cursor() 92 | sql='''CREATE TABLE IF NOT EXISTS theme 93 | ( theme_name text, 94 | username text ) ; 95 | ''' 96 | cursor.execute(sql) 97 | conn.commit() 98 | print("Table theme loaded successfully........") 99 | #Closing the connection 100 | except: 101 | print("Table theme is not loaded...") 102 | conn.close() 103 | 104 | def create_table5(): 105 | global conn 106 | try: 107 | #Creating table user if it not exists... 108 | cursor = conn.cursor() 109 | sql='''CREATE TABLE IF NOT EXISTS users 110 | (username text, 111 | password text ) ; 112 | ''' 113 | cursor.execute(sql) 114 | conn.commit() 115 | print("Table users loaded successfully........") 116 | #Closing the con 117 | except: 118 | print("Table users is not loaded...") 119 | conn.close() 120 | 121 | def shutdown_db(): 122 | """Close connection to db.""" 123 | print('Exit.') 124 | global conn 125 | conn.close() 126 | 127 | 128 | def add_user(values): 129 | cursor = conn.cursor() 130 | print(values[0]) 131 | print(values[1]) 132 | cursor.execute("INSERT INTO users (username, password) VALUES (%s, %s);", 133 | (values[0], values[1])) 134 | conn.commit() 135 | print("User added successfully") 136 | 137 | def get_users(): 138 | cursor = conn.cursor() 139 | cursor.execute("SELECT username,password from users;") 140 | rows_count = cursor.fetchall() 141 | return rows_count 142 | 143 | 144 | 145 | def add_task(values,username): 146 | """Add specified task to task table""" 147 | cursor = conn.cursor() 148 | cursor.execute("INSERT INTO tasks (task_name, priority_of_task, category, is_done,deadline,username) VALUES (%s, %s, %s, %s,%s,%s) RETURNING id;", 149 | (values[0], values[1], values[2], values[3],values[4],username)) 150 | 151 | text = cursor.fetchone()[0] 152 | conn.commit() 153 | print("Task added successfully") 154 | return text 155 | 156 | def get_tasks(username): 157 | """Get all tasks from the task table.""" 158 | cursor = conn.cursor() 159 | cursor.execute("SELECT id, task_name, priority_of_task, category, is_done,deadline from tasks where username=%s;",(username,)) 160 | rows_count = cursor.fetchall() 161 | return rows_count 162 | 163 | def edit_task(id, values): 164 | """Edit specified task in the task table.""" 165 | cursor = conn.cursor() 166 | cursor.execute("UPDATE tasks SET task_name = %s, priority_of_task = %s, category = %s, is_done = %s ,deadline=%s WHERE id = %s;", 167 | (values[0], values[1], values[2], values[3],values[4], id)) 168 | 169 | conn.commit() 170 | print("Number of records updated:", cursor.rowcount) 171 | 172 | def delete_task(id): 173 | """Delete specified task from the tasks table.""" 174 | cursor = conn.cursor() 175 | cursor.execute("DELETE from tasks where id = %s;", (id, )) 176 | conn.commit() 177 | print("Number of records deleted:", cursor.rowcount) 178 | 179 | def search_task(var,username): 180 | """Search specified task by its name/category/deadline from the tasks table """ 181 | cursor = conn.cursor() 182 | cursor.execute("SELECT category,task_name, deadline from tasks where (task_name=%s OR category=%s OR deadline=%s) AND username=%s;", (var,var,var,username)) 183 | rows = cursor.fetchall() 184 | return rows 185 | 186 | 187 | 188 | 189 | def add_email(values,username): 190 | cursor = conn.cursor() 191 | cursor.execute("INSERT INTO notification_email (from_email,password,to_email,time,username) VALUES (%s,%s,%s,%s,%s);", 192 | (values[0],values[1],values[2],values[3],username)) 193 | conn.commit() 194 | print("email added successfully") 195 | 196 | def get_email(username): 197 | cursor = conn.cursor() 198 | cursor.execute("SELECT from_email,password,to_email,time from notification_email where username=%s ORDER BY time DESC LIMIT 1;",(username,)) 199 | rows_count = cursor.fetchall() 200 | return rows_count 201 | 202 | 203 | 204 | def add_theme(themename,username): 205 | """Add current theme name to theme table.""" 206 | cursor = conn.cursor() 207 | cursor.execute("INSERT INTO theme(theme_name,username) VALUES (%s,%s);", 208 | (themename,username)) 209 | conn.commit() 210 | print("Theme saved.") 211 | 212 | def delete_theme(username): 213 | """Delete theme from the theme table. """ 214 | cursor = conn.cursor() 215 | cursor.execute("DELETE from theme where username=%s",(username,)) 216 | conn.commit() 217 | print("Number of records deleted:", cursor.rowcount) 218 | 219 | def get_theme(username): 220 | cursor = conn.cursor() 221 | cursor.execute("SELECT theme_name from theme where username=%s;",(username,)) 222 | rows_count = cursor.fetchall() 223 | return rows_count 224 | 225 | 226 | 227 | 228 | def add_notify_date(values,username): 229 | """Add specified task which is notified to user to the database.""" 230 | cursor = conn.cursor() 231 | cursor.execute("INSERT INTO notification_tracker(id,notify_date,username) VALUES (%s, %s,%s)", 232 | (values[0], values[5],username)) 233 | 234 | # text = cursor.fetchone()[0] 235 | conn.commit() 236 | print("Notifier date added to notification_tracker table") 237 | # return text 238 | 239 | def get_notified_tasks(username): 240 | """Get all tasks which are already notified from the database.""" 241 | cursor = conn.cursor() 242 | cursor.execute("SELECT id,notify_date from notification_tracker where username=%s;",(username,)) 243 | rows_count = cursor.fetchall() 244 | return rows_count 245 | 246 | 247 | def remove_item_notification_tracker(item_id): 248 | """Delete specified task from the notification_tracker table of database.""" 249 | cursor = conn.cursor() 250 | cursor.execute("DELETE from notification_tracker where id = %s;", (item_id, )) 251 | conn.commit() 252 | print("Number of records deleted:", cursor.rowcount) 253 | 254 | 255 | -------------------------------------------------------------------------------- /task_diary_main.py: -------------------------------------------------------------------------------- 1 | from tkinter import * 2 | import tkinter as tk 3 | from tkinter import ttk 4 | from tkinter import messagebox 5 | from tkinter import simpledialog 6 | from ttkthemes import themed_tk as ttkt 7 | import random 8 | from datetime import datetime 9 | from datetime import timedelta 10 | from datetime import date 11 | from dateutil.parser import parse 12 | import smtplib 13 | from email.mime.text import MIMEText 14 | from email.mime.multipart import MIMEMultipart 15 | import tkcalendar 16 | from tkcalendar import Calendar, DateEntry 17 | from start import username 18 | 19 | import db 20 | db.create_table() 21 | db.create_table2() 22 | db.create_table3() 23 | db.create_table4() 24 | 25 | tasks_due=[] 26 | 27 | 28 | root = ttkt.ThemedTk() #Main window 29 | tname=db.get_theme(username) 30 | if len(tname)==0 : #If youare opening for the first time default theme will be appear. 31 | root.set_theme('radiance') 32 | else: #else the theme last you change will be appear. 33 | root.set_theme(tname[0][0]) 34 | root.title("Task Diary") 35 | columns = ("task_name", "priority_of_task", "category", "is_done","deadline") 36 | #Table for the task 37 | tree = ttk.Treeview(root, height=36, selectmode="browse", columns=columns, show="headings") 38 | scrollbar = ttk.Scrollbar(root, orient=VERTICAL, command=tree.yview) 39 | tree.configure(yscrollcommand=scrollbar.set) 40 | tree.grid(row=0, column=0, rowspan=2) 41 | scrollbar.grid(row=0, column=1, rowspan=2, sticky=(W, N, E, S)) 42 | 43 | def already_notified(taskn): 44 | global UnboundLocalError 45 | for item in db.get_notified_tasks(username): 46 | if taskn[0]==item[0]: 47 | return True 48 | return False 49 | 50 | def notify(): 51 | global username 52 | #check the task date if its deadline is after 1 day, then notify user via email. 53 | for item in db.get_tasks(username): 54 | #check that the task is not notfied already 55 | if not already_notified(item): 56 | dd=datetime.strptime(item[5], "%d-%m-%Y") 57 | dd2= dd -timedelta(days=1) 58 | dd3=dd2.strftime('%d-%m-%Y') 59 | today=datetime.today().strftime('%d-%m-%Y') 60 | if (dd3==today) and (item[4]=="false"): #check whether the task is not completed 61 | email_notify(item) 62 | db.add_notify_date(item,username) 63 | print("Email notification sent sucessfully") 64 | 65 | 66 | def email_notify(item): 67 | global username 68 | row=db.get_email(username) 69 | if(len(row)==0): 70 | email ="task.diary534@gmail.com" #add your gmail id from which u want to sent (only gmail account) 71 | password ="task@diary"#add your email password 72 | send_to_email ="task.diary534@gmail.com"#add your email id where u want to sent (any mail account) 73 | else: 74 | email = row[0][0]#add your gmail id from which u want to sent (only gmail account) 75 | password = row[0][1]#add your email password 76 | send_to_email = row[0][2]#add your email id where u want to sent (any mail account) 77 | subject = 'Task Notifier'# The subject line 78 | message ='Category of task: '+item[3]+'\n\nYour Task:'+ item[1] 79 | msg = MIMEMultipart() 80 | msg['From'] = email 81 | msg['To'] = send_to_email 82 | msg['Subject'] = subject 83 | 84 | # Attach the message to the MIMEMultipart object 85 | msg.attach(MIMEText(message, 'plain')) 86 | server = smtplib.SMTP('smtp.gmail.com', 587) 87 | server.starttls() 88 | server.login(email, password) 89 | text = msg.as_string() # You now need to convert the MIMEMultipart object to a string to send 90 | server.sendmail(email, send_to_email, text) 91 | server.quit() 92 | 93 | def treeview_sort_column(treeview, column, reverse): 94 | children_list = [(treeview.set(child, column), child) for child in treeview.get_children("")] 95 | if(column=="priority_of_task"): 96 | children_list.sort(key=lambda column:int(column[0]),reverse=reverse) 97 | elif(column=="deadline"): 98 | children_list.sort(key=lambda column:datetime.strptime(column[0],'%d-%m-%Y'),reverse=reverse) 99 | else: 100 | children_list.sort(reverse=reverse) 101 | for index, (value, child) in enumerate(children_list): 102 | treeview.move(child, "", index) 103 | 104 | treeview.heading(column, command=lambda: treeview_sort_column(treeview, column, not reverse)) 105 | 106 | for column in columns: 107 | tree.heading(column, text=column, command=lambda col=column: treeview_sort_column(tree, col, False)) 108 | 109 | width, height = root.winfo_screenwidth(), root.winfo_screenheight() 110 | root.geometry("{0}x{1}+0+0".format(width, height)) 111 | 112 | width_task_name = int(width * 0.20) 113 | tree.column("task_name", width=width_task_name, anchor="center") 114 | tree.heading("task_name", text="Tasks") 115 | 116 | width_priority_of_task = int(width * 0.08) 117 | tree.column("priority_of_task", width=width_priority_of_task, anchor="center") 118 | tree.heading("priority_of_task", text="Priority") 119 | 120 | width_category = int(width * 0.15) 121 | tree.column("category", width=width_category, anchor="center") 122 | tree.heading("category", text="Category") 123 | 124 | width_is_done = int(width * 0.11) 125 | tree.column("is_done", width=width_is_done, anchor="center") 126 | tree.heading("is_done", text="Is Finished") 127 | 128 | width_deadline = int(width * 0.11) 129 | tree.column("deadline", width=width_is_done, anchor="center") 130 | tree.heading("deadline", text="Due date") 131 | 132 | mainframe = ttk.Frame(root, padding="25 25 100 50") 133 | mainframe.grid(row=0, column=2, sticky=(N, S, W, E)) 134 | mainframe.rowconfigure(0, weight=1) 135 | mainframe.columnconfigure(0, weight=1) 136 | 137 | task_name = StringVar() 138 | ttk.Label(mainframe, text="Task name:").grid(column=1, row=1, sticky=(W, E)) 139 | task_name_widget = ttk.Entry(mainframe, width=20, textvariable=task_name) 140 | task_name_widget.grid(column=2, row=1, sticky=(W, E)) 141 | 142 | priority_of_task = StringVar() 143 | ttk.Label(mainframe, text="Priority of task \n(E.g 1 to 10):").grid(column=1, row=2, sticky=(W, E)) 144 | priority_of_task_widget = ttk.Entry(mainframe, width=20, textvariable=priority_of_task) 145 | priority_of_task_widget.grid(column=2, row=2, sticky=(W, E)) 146 | 147 | category = StringVar() 148 | ttk.Label(mainframe, text="Category:").grid(column=1, row=3, sticky=(W, E)) 149 | category_widget = ttk.Entry(mainframe, width=20, textvariable=category) 150 | category_widget.grid(column=2, row=3, sticky=(W, E)) 151 | 152 | deadline = StringVar() 153 | ttk.Label(mainframe, text="Deadline: \n(Format:dd-mm-yyyy)").grid(column=1, row=4, sticky=(W, E)) 154 | deadline_widget = ttk.Entry(mainframe, width=20, textvariable=deadline) 155 | deadline_widget.grid(column=2, row=4, sticky=(W, E)) 156 | 157 | is_done = BooleanVar() 158 | ttk.Label(mainframe, text="Is Done:").grid(column=1, row=5, sticky=(W, E)) 159 | is_done_widget = ttk.Checkbutton(mainframe, variable=is_done, 160 | onvalue=True, offvalue=False) 161 | is_done_widget.grid(column=2, row=5, sticky=(W, E)) 162 | 163 | 164 | 165 | 166 | def create_task_item(): 167 | global username 168 | #get the task details 169 | task_name_value = task_name.get() 170 | priority_of_task_value = priority_of_task.get() 171 | category_value = category.get() 172 | is_done_value = is_done.get() 173 | deadline_value=deadline.get() 174 | 175 | if inputs_validation(): 176 | item_values = (task_name_value, 177 | priority_of_task_value, 178 | category_value, 179 | is_done_value, 180 | deadline_value) 181 | 182 | item_id = db.add_task(item_values,username) 183 | 184 | tree.insert("", "end", item_id, text=item_id, values=(item_values[0], 185 | item_values[1], 186 | item_values[2], 187 | item_values[3], 188 | item_values[4])) 189 | 190 | task_name.set("") 191 | priority_of_task.set("") 192 | category.set("") 193 | deadline.set("") 194 | is_done.set(False) 195 | 196 | create_button["state"] = "normal" 197 | change_button["state"] = "disabled" 198 | notify() 199 | 200 | 201 | def inputs_validation(): 202 | task_name_value = task_name.get() 203 | priority_of_task_value = priority_of_task.get() 204 | category_value = category.get() 205 | deadline_value=deadline.get() 206 | 207 | today=datetime.today().strftime('%d-%m-%Y') 208 | today1=datetime.strptime(today,"%d-%m-%Y") 209 | 210 | try: 211 | dd=datetime.strptime(deadline_value,"%d-%m-%Y") 212 | isNotValidDate = False 213 | except ValueError : 214 | isNotValidDate = True 215 | 216 | 217 | try: 218 | if not(len(task_name_value) <=25): 219 | messagebox.showerror("Task name", "Task name limit exceeded") 220 | return False 221 | if not(len(task_name_value) > 0 and len(task_name_value) <=25): 222 | messagebox.showerror("Task name", "Task name cannot be null") 223 | return False 224 | if not(int(priority_of_task_value) > 0 and int(priority_of_task_value) <= 10): 225 | messagebox.showerror("Priority", "Priority is not valid") 226 | return False 227 | 228 | if not( len(category_value) <= 15): 229 | messagebox.showerror("Category", "Category limit exceeded") 230 | return False 231 | 232 | if (isNotValidDate): 233 | messagebox.showwarning("Due date", "Not valid date!") 234 | return False 235 | 236 | if (dd", right_click_handler) 502 | 503 | 504 | def left_click_handler(event): 505 | menu.unpost() 506 | 507 | 508 | tree.bind("<1>", left_click_handler) 509 | notify() 510 | 511 | def shutdown_hook(): 512 | if messagebox.askyesno(message="Are you sure you want to quit?", 513 | icon="question", title="Quit"): 514 | db.shutdown_db() 515 | root.destroy() 516 | 517 | root.protocol("WM_DELETE_WINDOW", shutdown_hook) 518 | 519 | root.mainloop() --------------------------------------------------------------------------------