-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathteamwork.py
More file actions
188 lines (150 loc) · 5.69 KB
/
teamwork.py
File metadata and controls
188 lines (150 loc) · 5.69 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
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
import requests
import json
class Teamwork(object):
"""
Basic wrapper to work with the Teamwork API
Based on Teamwork API: http://developer.teamwork.com/
"""
def __init__(self, domain, api_key):
self._domain = domain
self._api_key = api_key
self._account = self.authenticate()
self._user = User(self._account.get('userId'))
def get(self, path=None, params=None, data=None):
url = self.get_base_url()
if path:
url = "%s/%s" % (url, path)
payload = {}
if params:
payload = params
request = requests.get(
url, auth=(self._api_key, ''), params=payload)
return request.json()
def post(self, path=None, data=None):
url = self.get_base_url()
if path:
url = "%s/%s" % (url, path)
request = requests.post(
url, auth=(self._api_key, ''), data=data)
if request.status_code != 201:
raise RuntimeError("Not Valid request")
return request.text
def get_base_url(self):
return 'https://%s' % self._domain
def authenticate(self):
result = self.get('authenticate.json')
return result.get('account')
def get_projects(self):
result = self.get('projects.json')
return result.get('projects')
def get_people(self):
result = self.get('people.json')
return result.get('people')
def get_project_times(self, project_id, user_id=None, start_date=None,
end_date=None):
"""
Get project time entries from project
http://developer.teamwork.com/timetracking#retrieve_all_time
GET /projects/{project_id}/time_entries.json
:param: user_id: User id
:param: start_date: Start date
:param: end_date: End Date
:type user_id: int
:type start_date: datetime.datetime
:type end_date: datetime.datetime
:returns: List of time entries
:rtype: list
"""
payload = {}
if start_date:
payload['fromdate'] = start_date.strftime('%Y%m%d')
if end_date:
payload['todate'] = end_date.strftime('%Y%m%d')
if user_id:
payload['userId'] = user_id
result = self.get("/projects/%i/time_entries.json" % project_id,
params=payload)
return result.get('time-entries')
def save_project_time_entry(self, project_id, entry_date, duration,
user_id, description, start_time, is_billable=True):
"""
:param: project_id: Project ID
:param: date: datetime.date Date of time entry
:param: duration: datetime.timedelta Duration
:param: user_id: Integer Id of person
:param: description: String Id of person
:param: start_time: datetime.timedelta
:param: is_billable: Boolean
"""
duration_hours, duration_minutes = timedelta_to_hours_minutes(duration)
if is_billable:
is_billable = "1"
else:
is_billable = "0"
data = {
"time-entry": {
"description": description,
"person-id": user_id,
"date": entry_date.strftime('%Y%m%d'),
"time": time_to_hhmm(start_time),
"hours": duration_hours,
"minutes": duration_minutes,
"isbillable": is_billable
}
}
result = self.post(
'/projects/%i/time_entries.json' % project_id,
data=json.dumps(data))
return result
def get_time_entry(self, time_id):
result = self.get('time_entries/%i.json' % time_id)
return result.get('time-entry')
def update_time_entry(self):
pass
def delete_time_entry(self):
pass
def update_project_time(self, project_id, data):
pass
def get_project_user_times(self, project_id, user_id):
pass
def get_project_tasks(self, project_id):
result = self.get('projects/%i/tasks.json' % project_id)
return result.get('todo-items')
def save_task_time_entry(self, task_id, entry_date, duration,
user_id, description, start_time, is_billable=True):
"""
:param: project_id: Project ID
:param: date: datetime.date Date of time entry
:param: duration: datetime.timedelta Duration
:param: user_id: Integer Id of person
:param: description: String Id of person
:param: start_time: datetime.timedelta
:param: is_billable: Boolean
"""
duration_hours, duration_minutes = timedelta_to_hours_minutes(duration)
if is_billable:
is_billable = "1"
else:
is_billable = "0"
data = {
"time-entry": {
"description": description,
"person-id": user_id,
"date": entry_date.strftime('%Y%m%d'),
"time": time_to_hhmm(start_time),
"hours": duration_hours,
"minutes": duration_minutes,
"isbillable": is_billable
}
}
result = self.post(
'/tasks/%i/time_entries.json' % task_id,
data=json.dumps(data))
return result
def timedelta_to_hours_minutes(td):
return td.seconds // 3600, (td.seconds // 60) % 60
def time_to_hhmm(time_input):
return '%i:%i' % (time_input.hour, time_input.minute)
class User(object):
def __init__(self, id):
self.id = id