-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.py
138 lines (111 loc) · 4.71 KB
/
main.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
from datetime import date
import json
from basecamp import Basecamp
from cement.core import foundation, controller
from cement.core.exc import InterfaceError, CaughtSignal
import elementtree.ElementTree as ET
from termcolor import colored
from settings import *
try:
bc = Basecamp(BASECAMP_API_URL, BASECAMP_API_KEY)
xml = bc.me()
me_tree = ET.fromstring(xml)
me = {}
me['id'] = me_tree.find('id').text
me['name'] = "{0} {1}".format(me_tree.find('first-name').text, me_tree.find('last-name').text)
print(colored("Hi {0}!".format(me['name']), 'yellow'))
except:
print(colored("Can't find ya bro. Check your api key.", 'red'))
quit()
class BasecampController(controller.CementBaseController):
class Meta:
label = 'base'
description = "Basecamp cli thingy"
config_defaults = dict()
arguments = [
(['-m', '--message'], dict(action='store', help='Time entry message')),
(['-t', '--hours'], dict(action='store', help='Time entry hours')),
(['-p', '--project'], dict(action='store', help='Time entry project')),
(['-d', '--date'], dict(action='store', help='Time entry date')),
(['-n', '--project-name'], dict(action='store', help='Time entry project by name')),
]
@controller.expose(help="get a list of projects")
def projects(self):
xml = bc.projects()
projects = ET.fromstring(xml).findall('.//project')
output = {}
for project in projects:
output[project.find("name").text] = project.find("id").text
for project in sorted(output):
print(colored("{0}: {1}".format(output[project], project), 'green'))
# Save the list of projects to file
with open('projects.json', 'w') as project_file:
json.dump(output, project_file)
@controller.expose(help="create time entry")
def time(self):
# If no project name, enter prompt mode
prompt_mode = not app.pargs.project_name
# Project name
if prompt_mode:
app.pargs.project_name = raw_input('Project Name: ')
# Try to look project up by name then id
if app.pargs.project_name:
project = self.project_name(app.pargs.project_name)
if len(project) == 1:
app.pargs.project = project.values()[0]
elif len(project) > 1:
raise InterfaceError('Too many projects found for the project "{}": {}'.format(app.pargs.project_name, ', '.join(project.keys())))
else:
raise InterfaceError('No projects found for "{}"'.format(app.pargs.project_name))
# Entry message
if prompt_mode and not app.pargs.message:
app.pargs.message = raw_input('Message: ')
# Entry hours
if prompt_mode and not app.pargs.hours:
app.pargs.hours = raw_input('Hours (eg. 1.5): ')
# Entry date
today = date.today().strftime("%Y-%m-%d")
if prompt_mode and not app.pargs.date:
app.pargs.date = raw_input('Date ({}): '.format(today))
# No date, use today as default
if not app.pargs.date:
app.pargs.date = today
if app.pargs.message and app.pargs.hours and app.pargs.project:
try:
bc.create_time_entry(app.pargs.message, float(app.pargs.hours), int(me['id']), entry_date=(app.pargs.date or None), project_id=int(app.pargs.project))
print(colored('{} hour{} added to {} on {}'.format(app.pargs.hours, 's' if app.pargs.hours > 1 else '', app.pargs.project, app.pargs.date), 'green'))
except:
raise InterfaceError(bc.last_error)
else:
raise InterfaceError('No projects saved yet. Run projects command first')
def project_name(self, name):
"Lookup a project id by it's name"
name = name.lower()
try:
with open('projects.json') as project_file:
project_names = json.load(project_file)
except IOError:
raise InterfaceError('No projects saved yet. Run projects command first')
matches = {}
for project_name in project_names:
if name in project_name.lower():
matches[project_name] = project_names[project_name]
return matches
class BasecampApp(foundation.CementApp):
class Meta:
label = 'basecamp-cli'
base_controller = BasecampController
# create the app
app = BasecampApp()
try:
# setup the application
app.setup()
# run the application
app.run()
except InterfaceError as exc:
print(colored(exc, 'red'))
except CaughtSignal as exc:
print(colored('See ya later!', 'yellow'))
finally:
# close the app
app.close()