Passed
Push — master ( fde0cc...eef757 )
by Alexander
01:33
created

things3.things3_cli   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 176
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 142
dl 0
loc 176
rs 10
c 0
b 0
f 0
wmc 12

3 Methods

Rating   Name   Duplication   Size   Complexity  
A Things3CLI.print_tasks() 0 15 4
A Things3CLI.__init__() 0 4 1
A Things3CLI.print_unimplemented() 0 4 1

2 Functions

Rating   Name   Duplication   Size   Complexity  
B get_parser() 0 92 1
A main() 0 19 5
1
#!/usr/bin/env python3
2
# -*- coding: utf-8 -*-
3
4
"""Simple read-only Thing 3 CLI."""
5
6
from __future__ import print_function
7
8
__author__ = "Alexander Willner"
9
__copyright__ = "2020 Alexander Willner"
10
__credits__ = ["Alexander Willner"]
11
__license__ = "Apache"
12
__version__ = "2.0.0"
13
__maintainer__ = "Alexander Willner"
14
__email__ = "[email protected]"
15
__status__ = "Development"
16
17
import sys
18
import argparse
19
import json
20
import csv
21
import webbrowser
22
from things3.things3 import Things3
23
24
25
class Things3CLI():
26
    """Simple read-only Thing 3 CLI."""
27
28
    print_json = False
29
    print_csv = False
30
    things3 = None
31
32
    def __init__(self, args, things):
33
        self.print_json = args.json
34
        self.print_csv = args.csv
35
        self.things3 = things
36
37
    def print_tasks(self, tasks):
38
        """Print a task."""
39
        if self.print_json:
40
            print(json.dumps(self.things3.convert_tasks_to_model(tasks)))
41
        elif self.print_csv:
42
            fieldnames = ['uuid', 'title', 'context', 'context_uuid', 'due',
43
                          'created', 'modified', 'started', 'stopped']
44
            writer = csv.DictWriter(sys.stdout, fieldnames=fieldnames)
45
            writer.writeheader()
46
            writer.writerows(self.things3.convert_tasks_to_model(tasks))
47
        else:
48
            for task in tasks:
49
                title = task[self.things3.I_TITLE]
50
                context = task[self.things3.I_CONTEXT]
51
                print(' - ', title, ' (', context, ')')
52
53
    @classmethod
54
    def print_unimplemented(cls):
55
        """Show warning that method is not yet implemented."""
56
        print("not implemented yet (see things.sh for a more complete CLI)")
57
58
59
def get_parser():
60
    """Create command line argument parser"""
61
    parser = argparse.ArgumentParser(
62
        description='Simple read-only Thing 3 CLI.')
63
64
    subparsers = parser.add_subparsers(help='',
65
                                       metavar="command",
66
                                       required=True,
67
                                       dest="command")
68
    subparsers.add_parser('inbox',
69
                          help='Shows all inbox tasks')
70
    subparsers.add_parser('today',
71
                          help='Shows all todays tasks')
72
    subparsers.add_parser('upcoming',
73
                          help='Shows all upcoming tasks')
74
    subparsers.add_parser('next',
75
                          help='Shows all next tasks')
76
    subparsers.add_parser('someday',
77
                          help='Shows all someday tasks')
78
    subparsers.add_parser('completed',
79
                          help='Shows all completed tasks')
80
    subparsers.add_parser('cancelled',
81
                          help='Shows all cancelled tasks')
82
    subparsers.add_parser('trashed',
83
                          help='Shows all trashed tasks')
84
    subparsers.add_parser('feedback',
85
                          help='Give feedback')
86
    subparsers.add_parser('all',
87
                          help='Shows all tasks')
88
    subparsers.add_parser('csv',
89
                          help='Exports all tasks as CSV')
90
    subparsers.add_parser('due',
91
                          help='Shows all tasks with due dates')
92
    subparsers.add_parser('headings',
93
                          help='Shows all headings')
94
    subparsers.add_parser('hours',
95
                          help='Shows how many hours have been planned today')
96
    subparsers.add_parser('ical',
97
                          help='Shows all tasks ordered by due date as iCal')
98
    subparsers.add_parser('logbook',
99
                          help='Shows all tasks completed today')
100
    subparsers.add_parser('mostClosed',
101
                          help='Shows days on which most tasks were closed')
102
    subparsers.add_parser('mostCancelled',
103
                          help='Shows days on which most tasks were cancelled')
104
    subparsers.add_parser('mostTrashed',
105
                          help='Shows days on which most tasks were trashed')
106
    subparsers.add_parser('mostCreated',
107
                          help='Shows days on which most tasks were created')
108
    subparsers.add_parser('mostTasks',
109
                          help='Shows projects that have most tasks')
110
    subparsers.add_parser('mostCharacters',
111
                          help='Shows tasks that have most characters')
112
    subparsers.add_parser('nextish',
113
                          help='Shows all nextish tasks')
114
    subparsers.add_parser('old',
115
                          help='Shows all old tasks')
116
    subparsers.add_parser('projects',
117
                          help='Shows all projects')
118
    subparsers.add_parser('repeating',
119
                          help='Shows all repeating tasks')
120
    subparsers.add_parser('schedule',
121
                          help='Schedules an event using a template')
122
    subparsers.add_parser('search',
123
                          help='Searches for a specific task')
124
    subparsers.add_parser('stat',
125
                          help='Provides a number of statistics')
126
    subparsers.add_parser('statcsv',
127
                          help='Exports some statistics as CSV')
128
    subparsers.add_parser('subtasks',
129
                          help='Shows all subtasks')
130
    subparsers.add_parser('tag',
131
                          help='Shows all tasks with the waiting for tag')
132
    subparsers.add_parser('tags',
133
                          help='Shows all tags ordered by their usage')
134
    subparsers.add_parser('waiting',
135
                          help='Shows all tasks with the waiting for tag')
136
137
    parser.add_argument("-j", "--json",
138
                        action="store_true", default=False,
139
                        help="output as JSON", dest="json")
140
141
    parser.add_argument("-c", "--csv",
142
                        action="store_true", default=False,
143
                        help="output as CSV", dest="csv")
144
145
    parser.add_argument(
146
        "--version",
147
        action="version",
148
        version="%(prog)s (version {version})".format(version=__version__))
149
150
    return parser
151
152
153
def main(args=None, things3=Things3()):
154
    """ Main entry point of the app """
155
156
    if args is None:
157
        main(get_parser().parse_args())
158
    else:
159
        things_cli = Things3CLI(args, things3)
160
        command = args.command
161
162
        if command in things3.functions:
163
            func = things3.functions[command]
164
            things_cli.print_tasks(func(things3))
165
        elif command == "csv":
166
            print("Deprecated: use --csv instead")
167
        elif command == "feedback":
168
            webbrowser.open(
169
                'https://github.com/AlexanderWillner/KanbanView/issues')
170
        else:
171
            Things3CLI.print_unimplemented()
172
173
174
if __name__ == "__main__":
175
    main(get_parser().parse_args())
176