-
Notifications
You must be signed in to change notification settings - Fork 0
/
todomanager.py
206 lines (170 loc) · 5.58 KB
/
todomanager.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
"""
main logic, file/directory reading and writing, cli options etc.
"""
# standard imports
import os
import sys
import glob
from projects import Project, ProjectList
from todos import ToDo, ToDoList
# Menu
def start():
"""
starts the ToDo manager menu.
:return: user_command (str)
"""
print("Welcome to Todo Manager.", end="")
print("""
_______________________________
C O M M A N D S
-------------------------------
v View all todos.
d Delete a todo.
a Add a project directory.
r Remove a project directory.
-------------------------------
""", end="")
print("What would you like to do?")
# take user input
user_command = ""
while not user_command:
user_command = input(" Enter a valid command: ")
if user_command.isalpha() and user_command.lower() in ("v", "d", "a", "r"):
user_command = user_command.lower()
return user_command
else:
user_command = ""
continue
# Functions to process the command returned from the menu
def show_todos_func():
"""
Prints the available todos
:return: None
"""
if default_todo_list.todos:
default_todo_list.show_todos()
else:
print("Sorry, no todos found!")
def delete_todos_func():
"""
Deletes a user selected todo.
:return:
"""
if default_todo_list.todos:
for idx, todo in enumerate(default_todo_list.todos):
print(idx + 1, ". ", todo.task)
num = int(input("Which todo you want to delete? enter number: "))
default_todo_list.remove_todo(num)
print("Todo deleted")
else:
print("Sorry, no todos found!")
def add_proj_func():
"""
Adds a projects to a project list
:return: None
"""
project = input("Give a name to your project: ")
default_project_list.add_project(project)
print("Project added")
def remove_proj_func():
"""
Removes a project from project list
:return: None
"""
if default_project_list.projects:
for idx, project in enumerate(default_project_list.projects):
print(idx + 1, ". ", project)
project_num_to_delete = int(input("Which project you wanna delete? Enter a number: ")) - 1
default_project_list.remove_project(project_num_to_delete)
print("Project deleted")
else:
print("Sorry, no projects found")
# define actions / features using dictionary to store reference to the related functions
actions = {
"v": show_todos_func,
"d": delete_todos_func,
"a": add_proj_func,
"r": remove_proj_func
}
# run the actions based on the command
def operation(user_command):
"""
Runs the operation
:param user_command: command returned by start() function
:return: None
"""
actions.get(user_command)()
print("Press ENTER to continue") # continue the loop
input()
user_command = start()
operation(user_command)
# ask for a project directory
def acquire_dir():
"""
Asks user to input the project directory name
:return: directory_name
"""
while True:
directory_name = input("Enter the Project directory address to scan for Todos."
"\n(Hint: /Users/username/ProjectDirectory)\nPress ENTER for current directory: ")
directory_name = os.path.join(os.getcwd(), directory_name)
if os.path.isdir(directory_name):
return directory_name
else:
print(directory_name, " does not exist. Provide a valid directory name!")
# read directory and return a list of files
def files_in_dir(directory_name, file_spec="*.py"):
"""
scan the directory and return a list of files.
:param directory_name: valid directory name retrived from acquire_dir() function
:param file_spec: type of files to include (str of extensions)
:return: list of files
"""
return glob.glob(os.path.join(directory_name, file_spec))
# function for finding todos
def file_match(files_list):
"""
read files in the list for "# todo:" tag
:param files_list: list containing file names with valid address
:return: list_of_extracted_todos
"""
list_of_extracted_todos = []
for ind_file in files_list:
with open(ind_file, "r") as read_content:
for todo_line in read_content.read().splitlines():
if "# todo:" in todo_line:
todo_line = todo_line.split("# todo:")[-1]
list_of_extracted_todos.append(todo_line)
return list_of_extracted_todos
def main():
user_command = start()
operation(user_command)
if __name__ == "__main__":
# create a ProjectList Obj
default_project_list = ProjectList()
# create a Project Obj
default_project = Project()
# create a ToDoList Obj
default_todo_list = ToDoList()
# create a ToDo Obj
default_todo = ToDo()
# get the project directory
directory_name = acquire_dir()
# create a list of files by scanning the directory (if we just want python files, we'd replace *.* with *.py
files_list = files_in_dir(directory_name, file_spec="*.*")
# create a list of extracted todos
todo_repo = file_match(files_list)
# create ToDo objs from todo_repo
todo_obj_list = [ToDo(task) for task in todo_repo]
# add the newly created ToDo obj in ToDoList obj
for ind_todo_obj in todo_obj_list:
default_todo_list.add_todo(ind_todo_obj)
# execute the main function
try:
main()
except KeyboardInterrupt:
print('Interrupted')
try:
sys.exit(0)
except SystemExit:
os._exit(0)