Skip to content

Commit cda1869

Browse files
author
Naglis Jonaitis
committed
sentry_openproject: rewrites plugin to use IssuePlugin2 API
WP#5401
1 parent 02036de commit cda1869

6 files changed

Lines changed: 440 additions & 119 deletions

File tree

sentry_openproject/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# -*- coding: utf-8 -*-
12
"""
23
sentry_openproject
34
~~~~~~~~~~~~~~~~~~

sentry_openproject/client.py

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
# -*- coding: utf-8 -*-
2+
from __future__ import absolute_import, unicode_literals
3+
4+
import base64
5+
6+
from requests.exceptions import HTTPError
7+
from sentry.http import build_session
8+
from sentry.utils import json
9+
10+
from .exceptions import ApiError
11+
12+
13+
class OpenProjectClient(object):
14+
15+
API_VERSION = 'v3'
16+
17+
def __init__(self, url, apikey):
18+
self.url = url.rstrip('/')
19+
self.apikey = apikey
20+
21+
def request(self, method, path, data=None, params=None):
22+
auth = base64.b64encode('apikey:%s' % self.apikey)
23+
headers = {
24+
'Authorization': 'Basic %s' % auth,
25+
}
26+
27+
path = path.lstrip('/')
28+
session = build_session()
29+
try:
30+
resp = getattr(session, method.lower())(
31+
url='{}/api/{}/{}'.format(
32+
self.url, OpenProjectClient.API_VERSION, path),
33+
headers=headers,
34+
json=data,
35+
params=params,
36+
allow_redirects=True,
37+
)
38+
resp.raise_for_status()
39+
except HTTPError as e:
40+
raise ApiError.from_response(e.response)
41+
return resp.json()
42+
43+
def get_work_package(self, work_package_id):
44+
return self.request(
45+
'GET',
46+
'work_packages/{}'.format(work_package_id),
47+
)
48+
49+
def create_work_package(self, project_id, title, work_package_type,
50+
description=None, assignee_id=None, notify=True,
51+
extra=None, **kwargs):
52+
data = {
53+
'subject': title,
54+
'description': {
55+
'format': 'textile',
56+
'raw': description,
57+
},
58+
'_links': {
59+
'type': {
60+
'href': '/api/{}/types/{}'.format(
61+
OpenProjectClient.API_VERSION, work_package_type),
62+
},
63+
},
64+
}
65+
if assignee_id:
66+
data['_links'].update({
67+
'assignee': {
68+
'href': '/api/{}/users/{}'.format(
69+
OpenProjectClient.API_VERSION, assignee_id)
70+
}
71+
})
72+
if extra:
73+
data.update(extra)
74+
return self.request(
75+
'POST',
76+
'projects/{}/work_packages'.format(project_id),
77+
data=data,
78+
params={'notify': 'true' if notify else 'false'},
79+
)
80+
81+
def create_comment(self, work_package_id, comment, notify=True,
82+
extra=None, **kwargs):
83+
data = {
84+
'comment': {
85+
'raw': comment,
86+
},
87+
}
88+
if extra:
89+
data.update(extra)
90+
return self.request(
91+
'POST',
92+
'work_packages/{}/activities/'.format(
93+
work_package_id,
94+
),
95+
params={'notify': 'true' if notify else 'false'},
96+
data=data,
97+
)
98+
99+
def list_assignees(self, project_id):
100+
return self.request(
101+
'GET',
102+
'projects/{}/available_assignees'.format(
103+
project_id),
104+
)
105+
106+
def list_projects(self):
107+
return self.request('GET', 'projects')
108+
109+
def list_project_types(self, project_id):
110+
return self.request(
111+
'GET',
112+
'projects/{}/types'.format(project_id),
113+
)
114+
115+
def search_work_packages(self, project_id, query):
116+
return self.request(
117+
'GET',
118+
'projects/{}/work_packages'.format(project_id),
119+
params={
120+
'filters': json.dumps([
121+
{
122+
'subject': {
123+
'operator': '~',
124+
'values': [
125+
query,
126+
],
127+
},
128+
},
129+
]),
130+
},
131+
)

sentry_openproject/exceptions.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# -*- coding: utf-8 -*-
2+
from __future__ import absolute_import, unicode_literals
3+
4+
import collections
5+
6+
from simplejson.decoder import JSONDecodeError
7+
from sentry.utils import json
8+
9+
'''
10+
Pretty much C/P from https://git.io/vXaVe
11+
'''
12+
13+
14+
class ApiError(Exception):
15+
code = None
16+
json = None
17+
xml = None
18+
19+
def __init__(self, text, code=None):
20+
if code is not None:
21+
self.code = code
22+
self.text = text
23+
if text:
24+
try:
25+
self.json = json.loads(
26+
text, object_pairs_hook=collections.OrderedDict)
27+
except (JSONDecodeError, ValueError):
28+
self.json = None
29+
else:
30+
self.json = None
31+
super(ApiError, self).__init__(text[:128])
32+
33+
@classmethod
34+
def from_response(cls, response):
35+
if response.status_code == 401:
36+
return ApiUnauthorized(response.text)
37+
return cls(response.text, response.status_code)
38+
39+
40+
class ApiUnauthorized(ApiError):
41+
code = 401

sentry_openproject/models.py

Lines changed: 0 additions & 7 deletions
This file was deleted.

0 commit comments

Comments
 (0)