-
Notifications
You must be signed in to change notification settings - Fork 0
/
todo.py
executable file
·163 lines (134 loc) · 4.49 KB
/
todo.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
import sys
from datetime import datetime
# Import click
try:
import click
except ImportError:
# Install click package if it doesn't exist
from io import StringIO
from pip._internal import main as pip
# Redirecting Standard output and error to String Streams
sys.stderr, sys.stdout = StringIO(), StringIO()
pip(['install', '--user', 'click'])
# Redirect standard output and error back to console
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__
import click
# Function to get help text
def get_help():
commands = [
'Usage :-',
'$ ./todo add "todo item" # Add a new todo',
'$ ./todo ls # Show remaining todos',
'$ ./todo del NUMBER # Delete a todo',
'$ ./todo done NUMBER # Complete a todo',
'$ ./todo help # Show usage',
'$ ./todo report # Statistics',
]
string = "\n".join(commands)
# Use buffer to write to make sure test pass on windows
sys.stdout.buffer.write(bytes(string, encoding='utf-8'))
sys.exit(0)
def add_todo_item(todo_item):
with open('todo.txt', 'a+') as f:
f.write(todo_item + "\n")
print(f'Added todo: "{todo_item}"')
def delete_todo(todo_number):
try:
with open('todo.txt', 'r+') as f:
data = f.readlines()
if todo_number == 0:
raise IndexError
item = data.pop(todo_number - 1)
with open('todo.txt', 'w') as f:
f.writelines(data)
return item
except (IndexError, FileNotFoundError):
return f'Error: todo #{todo_number} does not exist.'
def show_pending_todos():
try:
with open('todo.txt') as f:
data = f.readlines()
except FileNotFoundError:
print('There are no pending todos!')
sys.exit(0)
if len(data) == 0:
print('There are no pending todos!')
data = data[::-1]
pending_todos = len(data)
for i in range(pending_todos):
# Use buffer to write to make sure test pass on windows
sys.stdout.buffer.write(
bytes(f'[{pending_todos-i}] {data[i]}', encoding='utf-8')
)
# Mark a todo as Done
def complete_todo(todo_number):
# Call delete_todo to remove item from todo list
todo_item = delete_todo(todo_number)
# Check if there was an error
if todo_item.startswith('Error'):
print(todo_item)
sys.exit(0)
# Get current date in UTC format
today_date = datetime.utcnow().strftime('%Y-%m-%d')
with open('done.txt', 'a+') as f:
f.write(f'x {today_date} {todo_item}')
# Get Statistics
def get_report():
try:
with open('todo.txt', 'r+') as f:
pending = len(f.readlines())
except FileNotFoundError:
pending = 0
try:
with open('done.txt', 'r+') as f:
completed = len(f.readlines())
except FileNotFoundError:
completed = 0
today_date = datetime.utcnow().strftime('%Y-%m-%d')
print(f'{today_date} Pending : {pending} Completed : {completed}')
@click.command()
@click.argument('arg', nargs=-1) # Taking all arguments provided in a tuple
def main(arg):
# show help to user
if len(arg) == 0 or arg[0] == 'help':
get_help()
# Add item to todo
elif arg[0] == 'add':
try:
add_todo_item(arg[1])
except IndexError:
print('Error: Missing todo string. Nothing added!')
# Remove item from todo
elif arg[0] == 'del':
try:
number = int(arg[1])
todo_item = delete_todo(number)
if todo_item.startswith('Error'):
print(todo_item, "Nothing deleted.")
else:
print(f'Deleted todo #{number}')
except ValueError:
print('Error: Please provide a valid number to delete item')
except IndexError:
print('Error: Missing NUMBER for deleting todo.')
# Show pending todos
elif arg[0] == 'ls':
show_pending_todos()
# Mark a todo as done
elif arg[0] == 'done':
try:
number = int(arg[1])
complete_todo(number)
print(f'Marked todo #{number} as done.')
except IndexError:
print('Error: Missing NUMBER for marking todo as done.')
# Get Report of Pending and Completed todos
elif arg[0] == 'report':
get_report()
# Giving help when a wrong option is selected
else:
print('Please select valid option')
get_help()
if __name__ == '__main__':
main()