· 6 years ago · Dec 01, 2019, 11:54 AM
1#!/usr/bin/env python3
2import sqlite3, sys, os, hashlib, time
3
4# Requirements: None
5# no installation required
6
7welcome = """
8WELCOME TO
9==> Bit TODO (Text-Based Interface)<== V5.9x-STABLE
10© Samuel Cheng 2019
11License: GPL-3.0 -> gnu.org/licenses/gpl-3.0.en.html
12Powered by SQLite3 for Python 3
13
14 __...--~~~~~-._ _.-~~~~~--...__
15 // `V' \\
16 // BIT | TODO \\
17 //__...--~~~~~~-._ | _.-~~~~~~--...__\\
18 //__.....----~~~~._\ | /_.~~~~----.....__\\
19====================\\\\|//====================
20 `---`
21
22email extrasupermega@gmx.us for bug report!
23SUB to my Youtube Channel [Mellifluous Meditations] PLS support me by clicking this link!
24http://gestyy.com/w6uivq
25"""
26
27
28class sql:
29 exit_if = ["e", "exit"]
30 help_if = ["h", "help"]
31 createTable_bool = True
32 createTable = """
33CREATE TABLE ToDo (
34 Item varchar(255),
35 Done varchar(255),
36 User varchar(255),
37 Name varchar(255)
38);"""
39 ####PROBLEM
40 insert = """
41INSERT INTO ToDo (Item, Done, User, Name)
42VALUES ('{item}', 'False', '{user}', '{name}');
43"""
44 delete = """
45DELETE FROM ToDo WHERE Item = "{item}" AND User = "{user}" AND Name = "{name}"
46"""
47 toggle_true = """
48UPDATE ToDo SET Done="False" WHERE Item = "{item}" AND User = "{user}" AND Name = '{name}'
49"""
50 toggle_false = """
51UPDATE ToDo SET Done="True" WHERE Item = "{item}" AND User = "{user}" AND Name = '{name}'
52"""
53 toggle_check = """
54SELECT Done FROM ToDo Where Item = "{item}" AND User = "{user}" AND Name = '{name}'
55"""
56 find_all_distinct = """
57SELECT DISTINCT Name FROM ToDo WHERE User = "{user}"
58"""
59 commands = ["exit", "add", "display", "delete", "toggle", "switchlist", "addlist", "deletelist", "displaylist"]
60 commands_help = ["Type in \"exit\" to exit!", "Type in \"add [item]\" to add item to database",
61 "Type in \"Display\" to display todo list!",
62 "Type in \"delete [item]\" to delete an item",
63 "Type in \"toggle [item]\" to toggle between DONE and NOT DONE",
64 "Type in \"switchlist\" to switch to an available TODO list!",
65 "Type in \"addlist [item]\" to add a TODO list!",
66 "Type in \"deletelist [item]\" to delete a list!",
67 "Type in \"displaylist\" to display all the available TODO lists for your user"]
68
69 database = 'ToDo.db'
70
71 def __init__(self, *args, **kwargs):
72 # init connection to database
73 self.connection = sqlite3.connect(sql.database)
74 self.databasename = "main"
75 print("[LOG] Connected to SQLite")
76
77 # init cursor for database
78 self.crsr = self.connection.cursor()
79 print("[LOG] SQLite cursor INITIALIZED")
80
81 # if createtable_bool is true, create table
82 if sql.createTable_bool:
83 try:
84 self.crsr.execute(sql.createTable)
85
86 except:
87 print("Database already exists!\nsetting createTable_bool to False")
88 sql.createTable_bool = False
89 pass
90
91 @staticmethod
92 def parse_action(self, first):
93 if first.__len__() == 0:
94 print("Enter an action followed by a string.\nOr an action\ne.g. exit, help")
95 main.input(main)
96 # Check exit
97 self.parse = first[0].lower()
98 for element in sql.exit_if:
99 if element == self.parse:
100 print("Exiting!")
101 time.sleep(1)
102 sys.exit()
103
104 for element in sql.help_if:
105 if element == self.parse:
106 print("HELP!")
107 for i in range(sql.commands.__len__()):
108 print(sql.commands[i], sql.commands_help[i], sep="\n")
109 main.input(main)
110 valid_command = False
111 for element in sql.commands:
112 if element == self.parse:
113 valid_command = True
114 continue
115 if not valid_command:
116 print("Not a valid command!\nType [help] for list of commands")
117
118 @staticmethod
119 def e(self):
120
121 # exec gonna be in list format
122 sql.mainparse(self)
123
124 # commit changes
125 self.connection.commit()
126 print("[LOG] CHANGE to database COMMITED")
127
128 @staticmethod
129 def add_func(self):
130 self.crsr.execute(sql.insert.format(item=command.item, user=self.username, name=self.databasename))
131 sql.display_func(self)
132
133 @staticmethod
134 def display_func(self):
135 with self.connection:
136 self.crsr.execute(
137 """SELECT * FROM ToDo WHERE User = '{user}' AND Name = '{name}'""".format(user=self.username,
138 name=self.databasename))
139 self.display_database = self.crsr.fetchall()
140 print("GETTING data from \"{name}\"".format(name=self.databasename))
141 print("\n\nITEM, DONE_STATUS")
142 # TODO enumerate self.display_database
143 for element in self.display_database:
144 for i, x in enumerate(element):
145 if i == 0:
146 print(x, end=", ")
147 elif i == 1:
148 print(x)
149 print()
150
151 @staticmethod
152 def delete_func(self):
153
154 self.crsr.execute(sql.delete.format(item=command.item, user=self.username, name=self.databasename))
155 print("DELETED {}!".format(command.item))
156 sql.display_func(self)
157
158 @staticmethod
159 def toggle_func(self):
160 if not command.item:
161 print("Type in an object to toggle!")
162 main.input(main)
163 try:
164 for element in self.crsr.execute(
165 sql.toggle_check.format(item=command.item, user=self.username, name=self.databasename)).fetchone():
166 self.toggle_check_var = element
167 except TypeError:
168 print("There is no such item in the database!")
169 main.input(main)
170
171 if self.toggle_check_var == "True":
172 self.crsr.execute(sql.toggle_true.format(item=command.item, user=self.username, name=self.databasename))
173
174 else:
175 self.crsr.execute(sql.toggle_false.format(item=command.item, user=self.username, name=self.databasename))
176 sql.display_func(self)
177
178 @staticmethod
179 def switch_func(self):
180 all_todo = []
181 foundindex = ""
182 with self.connection:
183 self.crsr.execute(sql.find_all_distinct.format(user=self.username))
184 self.display_database = self.crsr.fetchall()
185 print("Here are the available TODO lists:\n")
186 for element in self.display_database:
187 print(element[0])
188 all_todo.append(element[0])
189
190 print()
191 raw = input("Which TODO list do you want to switch to?\n>>> ").lower()
192
193 # Same search engine
194 found = False
195 for element in all_todo:
196 if element.lower() == raw:
197 found = True
198 foundindex = element
199 if not found:
200 print("TODO list is not found!\n(Tip: Make a new TODO list)")
201 main.input(main)
202 elif found:
203 self.databasename = foundindex
204 print("Switched TODO list!\n")
205 else:
206 print("Bit TODO has run into an unexpected problem.\nError Code: [switch_func]")
207
208 @staticmethod
209 def addtodo_func(self):
210 if not command.item:
211 print("Cannot make the name of a TODO list empty! Try again with \"addlist [item]\"!\n")
212 main.input(main)
213 with self.connection:
214 self.crsr.execute('SELECT DISTINCT Name FROM Todo WHERE User = "{user}"'.format(user=self.username))
215 self.display_database = self.crsr.fetchall()
216 for element in self.display_database:
217 if element[0] == command.item:
218 print("Cannot create a TODO list that already exists!\n")
219 main.input(main)
220 self.databasename = command.item
221 print("Switching to {list}!\n".format(list=self.databasename))
222 print("[WARNING!]:\nIf this TODO list is empty and TODO list is switched, this TODO list will be erased!\n")
223
224 @staticmethod
225 def deletelist_func(self):
226 all_todo = []
227 if not command.item:
228 print("Cannot make the name of a TODO list empty! Try again with \"deletelist [item]\"!\n")
229 main.input(main)
230
231 with self.connection:
232 self.crsr.execute(sql.find_all_distinct.format(user=self.username))
233 self.display_database = self.crsr.fetchall()
234 print("Here are the available TODO lists:\n")
235 for element in self.display_database:
236 print(element[0])
237 all_todo.append(element[0])
238
239 if command.item == "main":
240 print("Default list cannot be deleted!\n")
241 main.input(main)
242
243 for list in all_todo:
244 if list == command.item:
245 print("Deleting TODO list...")
246 self.crsr.execute(
247 """DELETE FROM ToDo WHERE Name = "{name}" AND User = '{user}'""".format(name=self.databasename,
248 user=self.username))
249 print("TODO list DELETED!\n")
250 if self.databasename == list:
251 self.databasename = "main"
252 print("Switching TODO list to default (main)\n")
253
254 @staticmethod
255 def defineusername(self, user):
256 self.username = user
257
258 @staticmethod
259 def mainparse(self):
260 if command.action == "add":
261 sql.add_func(self)
262
263 if command.action == "display":
264 sql.display_func(self)
265
266 if command.action == "delete":
267 sql.delete_func(self)
268
269 if command.action == "toggle":
270 sql.toggle_func(self)
271
272 if command.action == "switchlist":
273 sql.switch_func(self)
274
275 if command.action == "addlist":
276 sql.addtodo_func(self)
277
278 if command.action == "deletelist":
279 sql.deletelist_func(self)
280
281
282# TODO change tools to command
283class command:
284
285 def __init__(self):
286 self.action = ""
287 self.item = ""
288
289 @staticmethod
290 def usr_input(self, raw):
291 command()
292 self.raw = raw.split()
293 sql.parse_action(sql, self.raw)
294 self.action = self.raw[0].lower()
295 self.item = ' '.join(self.raw[1:])
296 sql.e(sql)
297
298
299class setup:
300 text = """
301+------------------+
302|Setup for BIT TODO|
303+------------------+
304"""
305 success = """
306+----------------+
307|Setup Completed!|
308+----------------+
309"""
310 createTable = """
311CREATE TABLE Secure (
312 Username varchar(255),
313 Password varchar(255)
314);"""
315 insert = """
316INSERT INTO Secure (Username, Password)
317VALUES ('{0}', '{1}');
318"""
319 temp = []
320 userinfo = []
321
322 def __init__(self):
323 print(setup.text)
324 print("Running from: {}".format(os.path.dirname(os.path.realpath(__file__))))
325 setup.sql(self)
326 sql.databasename = "main"
327 # setup.database(self)
328 # setup.createtable(self)
329 setup.loginorsignup(self)
330 print(setup.success)
331
332 @staticmethod
333 def sql(self):
334 # Check if database exists
335 # if not exists, create new table
336 self.connection = sqlite3.connect("Users.db")
337 self.crsr = self.connection.cursor()
338 try:
339 self.crsr.execute(setup.createTable)
340 print("[LOG] Users.db does not exist!")
341 except:
342 print("[LOG] Users.db exists!")
343 pass
344 with self.connection:
345 self.crsr.execute("SELECT * FROM Secure")
346 self.display_database = self.crsr.fetchall()
347
348 @staticmethod
349 def loginorsignup(self):
350 raw = input("[LOGIN] or [SIGN UP]?\n").lower()
351 if raw == "login":
352 setup.login(self)
353 elif raw == "sign up":
354 setup.signup(self)
355 else:
356 print("Not a valid option!\n")
357 setup.loginorsignup(self)
358
359 @staticmethod
360 def login(self):
361 user = input("Username: ")
362 password = input("Password: ")
363 founduser = False
364 for element in self.display_database:
365 if element[0] == user and element[1] == hashlib.md5(password.encode()).hexdigest():
366 print("Logged in as {}".format(element[0]))
367 founduser = True
368 sql.defineusername(sql, user)
369 return
370 if not founduser:
371 print("Either Username or Password is incorrect! Try again.")
372 setup.loginorsignup(self)
373
374 @staticmethod
375 def signup(self):
376 print("Sign up as new USER")
377 user = input("Username: ")
378 password = input("Password: ")
379 found = False
380 with self.connection:
381 # Yes, distinct is a bit extra
382 self.crsr.execute("SELECT DISTINCT Username FROM Secure")
383 self.display_database = self.crsr.fetchall()
384 # Check if recurring usernames
385 for element in self.display_database:
386 if element[0] == user:
387 found = True
388 if found:
389 print("Username is not available!\n")
390 setup.loginorsignup()
391 print("Username Available!\n")
392 self.crsr.execute(setup.insert.format(user, hashlib.md5(password.encode()).hexdigest()))
393 print("Signed up!\nRedirecting you back to LOGIN OR SIGNUP\n")
394 self.connection.commit()
395 setup.loginorsignup(self)
396
397
398class main(object):
399
400 def __init__(self):
401 setup()
402 print(welcome)
403 # Faster init sql
404 sql.__init__(sql)
405 while True:
406 main.input(self)
407
408 @staticmethod
409 def input(self):
410 command.usr_input(command, input(">>>"))
411
412
413if __name__ == "__main__":
414 main()