Skip to content

Commit

Permalink
bitbucket: More v2 API. Progress on #129.
Browse files Browse the repository at this point in the history
- Moving most things to the v2 API makes some things cleaner.
- One DRY get_data function that takes an optional api kwarg.
- Still no way to get detailed comment data without making an extra api
  call, so let's put that off for now.
  • Loading branch information
ryneeverett committed Feb 18, 2016
1 parent 7c5638f commit 1b5b714
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 43 deletions.
62 changes: 21 additions & 41 deletions bugwarrior/services/bitbucket.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,15 @@ def to_taskwarrior(self):
'annotations': self.extra['annotations'],

self.URL: self.extra['url'],
self.FOREIGN_ID: self.record['local_id'],
self.FOREIGN_ID: self.record['id'],
self.TITLE: self.record['title'],
}

def get_default_description(self):
return self.build_default_description(
title=self.record['title'],
url=self.get_processed_url(self.extra['url']),
number=self.record['local_id'],
number=self.record['id'],
cls='issue'
)

Expand Down Expand Up @@ -102,7 +102,9 @@ def get_keyring_service(cls, config, section):
username = config.get(section, cls._get_key('username'))
return "bitbucket://%[email protected]/%s" % (login, username)

def filter_repos(self, repo):
def filter_repos(self, repo_tag):
repo = repo_tag.split('/').pop()

if self.exclude_repos:
if repo in self.exclude_repos:
return False
Expand All @@ -115,25 +117,9 @@ def filter_repos(self, repo):

return True

def get_data2(self, url):
response = requests.get(self.BASE_API2 + url, auth=self.auth)

# And.. if we didn't get good results, just bail.
if response.status_code != 200:
raise IOError(
"Non-200 status code %r; %r; %r" % (
response.status_code, url, response.text,
)
)
if callable(response.json):
# Newer python-requests
return response.json()
else:
# Older python-requests
return response.json

def get_data(self, url):
response = requests.get(self.BASE_API + url, auth=self.auth)
def get_data(self, url, **kwargs):
api = kwargs.get('api', self.BASE_API2)
response = requests.get(api + url, auth=self.auth)

# And.. if we didn't get good results, just bail.
if response.status_code != 200:
Expand All @@ -158,16 +144,16 @@ def validate_config(cls, config, target):

def fetch_issues(self, tag):
response = self.get_data('/repositories/%s/issues/' % (tag))
return [(tag, issue) for issue in response['issues']]
return [(tag, issue) for issue in response['values']]

def fetch_pull_requests(self, tag):
response = self.get_data2('/repositories/%s/pullrequests/' % tag)
response = self.get_data('/repositories/%s/pullrequests/' % tag)
return [(tag, issue) for issue in response['values']]

def get_annotations(self, tag, issue, issue_obj, url):
response = self.get_data(
'/repositories/%s/issues/%i/comments' % (tag, issue['local_id'])
)
'/repositories/%s/issues/%i/comments' % (tag, issue['id']),
api=self.BASE_API)
return self.build_annotations(
((
comment['author_info']['username'],
Expand All @@ -177,7 +163,7 @@ def get_annotations(self, tag, issue, issue_obj, url):
)

def get_annotations2(self, tag, issue, issue_obj, url):
response = self.get_data2(
response = self.get_data(
'/repositories/%s/pullrequests/%i/comments' % (tag, issue['id'])
)
return self.build_annotations(
Expand All @@ -194,14 +180,13 @@ def get_owner(self, issue):

def issues(self):
user = self.config.get(self.target, 'bitbucket.username')
response = self.get_data('/users/' + user + '/')
all_repos = [
repo.get('slug') for repo in response.get('repositories')
response = self.get_data('/repositories/' + user + '/')
repo_tags = filter(self.filter_repos, [
repo['full_name'] for repo in response.get('values')
if repo.get('has_issues')
]
repos = filter(self.filter_repos, all_repos)
])

issues = sum([self.fetch_issues(user + "/" + repo) for repo in repos], [])
issues = sum([self.fetch_issues(repo) for repo in repo_tags], [])
log.name(self.target).debug(" Found {0} total.", len(issues))

closed = ['resolved', 'duplicate', 'wontfix', 'invalid', 'closed']
Expand All @@ -212,9 +197,7 @@ def issues(self):

for tag, issue in issues:
issue_obj = self.get_issue_for_record(issue)
url = self.BASE_URL + '/'.join(
issue['resource_uri'].split('/')[3:]
).replace('issues', 'issue')
url = issue['links']['html']['href']
extras = {
'project': tag.split('/')[1],
'url': url,
Expand All @@ -224,7 +207,8 @@ def issues(self):
yield issue_obj

if not self.filter_merge_requests:
pull_requests = sum([self.fetch_pull_requests(user + "/" + repo) for repo in repos], [])
pull_requests = sum(
[self.fetch_pull_requests(repo) for repo in repo_tags], [])
log.name(self.target).debug(" Found {0} total.", len(pull_requests))

closed = ['rejected', 'fulfilled']
Expand All @@ -234,10 +218,6 @@ def issues(self):
log.name(self.target).debug(" Pruned down to {0}", len(pull_requests))

for tag, issue in pull_requests:
# Pull requests are only accessible over API v2.0 which has
# this difference.
issue['local_id'] = issue['id']

issue_obj = self.get_issue_for_record(issue)
url = self.BASE_URL + '/'.join(
issue['links']['html']['href'].split('/')[3:]
Expand Down
4 changes: 2 additions & 2 deletions tests/test_bitbucket.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def setUp(self):
def test_to_taskwarrior(self):
arbitrary_issue = {
'priority': 'trivial',
'local_id': '100',
'id': '100',
'title': 'Some Title',
}
arbitrary_extra = {
Expand All @@ -36,7 +36,7 @@ def test_to_taskwarrior(self):
'annotations': arbitrary_extra['annotations'],

issue.URL: arbitrary_extra['url'],
issue.FOREIGN_ID: arbitrary_issue['local_id'],
issue.FOREIGN_ID: arbitrary_issue['id'],
issue.TITLE: arbitrary_issue['title'],
}
actual_output = issue.to_taskwarrior()
Expand Down

0 comments on commit 1b5b714

Please sign in to comment.