-
Notifications
You must be signed in to change notification settings - Fork 89
Expand file tree
/
Copy pathmain.py
More file actions
110 lines (84 loc) · 3.03 KB
/
main.py
File metadata and controls
110 lines (84 loc) · 3.03 KB
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
"""
Usage:
main.py list -s done|pending|all(D)
main.py create [TASK NAME] -d [DESCRIPTION] -p [PENDING DUE DATE]
main.py complete id | [TASK NAME]
Homework:
* Add the "filter by date" functionality to list
"""
import os
import json
import click
import todos
def _debug(msg):
ctx = click.get_current_context()
if ctx.obj['debug']:
click.echo(msg)
def _json_dumps(obj):
ctx = click.get_current_context()
return json.dumps(obj, indent=ctx.obj['indent'])
@click.group()
@click.option('--debug/--no-debug', default=False)
@click.option('-i', '--indent', type=int, default=2)
@click.option('-f', '--data-file', default='todo_data.json')
@click.pass_context
def cli(ctx, debug, indent, data_file):
ctx.obj['debug'] = debug
ctx.obj['indent'] = indent
_debug('Debug mode is %s' % ('on' if debug else 'off'))
data_file_path = os.path.abspath(data_file)
ctx.obj['data_file'] = data_file
ctx.obj['data_file_path'] = data_file_path
if not os.path.exists(data_file_path):
with open(data_file_path, 'w') as fp:
_debug('Task file created: {}'.format(data_file_path))
tasks = todos.new()
fp.write(_json_dumps(tasks))
elif os.path.isdir(data_file_path):
ctx.fail('Data file {} is a directory'.format(data_file))
with open(data_file_path, 'r') as fp:
# Task 1: Check the format of file and prevent:
# json.decoder.JSONDecodeError
ctx.obj['json_data'] = todos.unserialize(fp.read())
_debug('Read tasks from task file {}'.format(data_file_path))
@cli.command()
@click.option(
'-s', '--status',
type=click.Choice(['all', 'pending', 'done']), default='pending')
@click.pass_context
def list(ctx, status):
tasks = todos.list_tasks(ctx.obj['json_data'], status=status)
summary = todos.summary(ctx.obj['json_data'])
click.echo('{} tasks. {} pending. {} done.'.format(
summary['total'], summary['pending'], summary['done']))
print('-' * 60)
tpl = "{:>10} | {:^30} | {:>10}"
print(tpl.format('| #', 'Task', 'Status |'))
print('-' * 60)
for task in tasks:
idx, name, due_on, status = task
print(tpl.format(idx, name, status))
print('-' * 60)
@cli.command()
@click.argument('name')
@click.option('-d', '--description')
@click.option('-p', '--due-on', help='Date Formats: 2018-01-01 19:30:51')
@click.pass_context
def create(ctx, name, description, due_on):
tasks = ctx.obj['json_data']
todos.create_task(
tasks, name, description=description, due_on=due_on)
serialized = todos.serialize(tasks)
with open(ctx.obj['data_file_path'], 'w') as fp:
fp.write(_json_dumps(serialized))
@cli.command()
@click.argument('name')
@click.pass_context
def complete(ctx, name):
new_tasks = todos.complete_task(ctx.obj['json_data'], name)
serialized = todos.serialize(new_tasks)
with open(ctx.obj['data_file_path'], 'w') as fp:
fp.write(_json_dumps(serialized))
click.echo("Task {}. Done!".format(name))
if __name__ == '__main__':
cli(obj={})