Skip to content

Commit ea0d2d5

Browse files
Moving Github/Bitbucket object create logic from helper functions into appropriate manager methods.
1 parent 0a82c33 commit ea0d2d5

File tree

4 files changed

+136
-85
lines changed

4 files changed

+136
-85
lines changed

readthedocs/oauth/managers.py

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import logging
2+
3+
from django.conf import settings
4+
from django.db import models
5+
6+
7+
logger = logging.getLogger(__name__)
8+
9+
10+
GITHUB_PRIVACY = getattr(settings, 'GITHUB_PRIVACY', 'public')
11+
BITBUCKET_PRIVACY = getattr(settings, 'BITBUCKET_PRIVACY', GITHUB_PRIVACY)
12+
13+
14+
class GithubProjectManager(models.Manager):
15+
def create_from_api(self, api_json, user, organization=None,
16+
privacy=GITHUB_PRIVACY):
17+
logger.info('Trying GitHub: %s' % api_json['full_name'])
18+
if (
19+
(api_json['private'] is True and privacy == 'private') or
20+
(api_json['private'] is False and privacy == 'public')):
21+
project, created = self.get_or_create(
22+
full_name=api_json['full_name'],
23+
users__pk=user.pk,
24+
)
25+
if project.organization and project.organization != organization:
26+
logger.debug('Not importing %s because mismatched orgs' %
27+
api_json['name'])
28+
return None
29+
else:
30+
project.organization = organization
31+
project.users.add(user)
32+
project.name = api_json['name']
33+
project.description = api_json['description']
34+
project.git_url = api_json['git_url']
35+
project.ssh_url = api_json['ssh_url']
36+
project.html_url = api_json['html_url']
37+
project.json = api_json
38+
project.save()
39+
return project
40+
else:
41+
logger.debug('Not importing %s because mismatched type' %
42+
api_json['name'])
43+
44+
45+
class GithubOrganizationManager(models.Manager):
46+
def create_from_api(self, api_json, user):
47+
organization, created = self.get_or_create(login=api_json.get('login'))
48+
organization.html_url = api_json.get('html_url')
49+
organization.name = api_json.get('name')
50+
organization.email = api_json.get('email')
51+
organization.json = api_json
52+
organization.users.add(user)
53+
organization.save()
54+
return organization
55+
56+
57+
class BitbucketProjectManager(models.Manager):
58+
def create_from_api(self, api_json, user, organization=None,
59+
privacy=BITBUCKET_PRIVACY):
60+
logger.info('Trying Bitbucket: %s' % api_json['full_name'])
61+
if (api_json['is_private'] is True and privacy == 'private' or
62+
api_json['is_private'] is False and privacy == 'public'):
63+
project, created = self.get_or_create(
64+
full_name=api_json['full_name'])
65+
if project.organization and project.organization != organization:
66+
logger.debug('Not importing %s because mismatched orgs' %
67+
api_json['name'])
68+
return None
69+
else:
70+
project.organization = organization
71+
project.users.add(user)
72+
project.name = api_json['name']
73+
project.description = api_json['description']
74+
project.git_url = api_json['links']['clone'][0]['href']
75+
project.ssh_url = api_json['links']['clone'][1]['href']
76+
project.html_url = api_json['links']['html']['href']
77+
project.vcs = api_json['scm']
78+
project.json = api_json
79+
project.save()
80+
return project
81+
else:
82+
logger.debug('Not importing %s because mismatched type' %
83+
api_json['name'])
84+
85+
86+
class BitbucketTeamManager(models.Manager):
87+
pass

readthedocs/oauth/models.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
from django.contrib.auth.models import User
33
from django.utils.translation import ugettext_lazy as _
44

5+
from .managers import BitbucketTeamManager
6+
from .managers import BitbucketProjectManager
7+
from .managers import GithubOrganizationManager
8+
from .managers import GithubProjectManager
9+
510

611
class GithubOrganization(models.Model):
712
# Auto fields
@@ -20,6 +25,8 @@ class GithubOrganization(models.Model):
2025
active = models.BooleanField(_('Active'), default=False)
2126
json = models.TextField('JSON')
2227

28+
objects = GithubOrganizationManager()
29+
2330
def __unicode__(self):
2431
return "GitHub Organization: %s" % (self.html_url)
2532

@@ -44,6 +51,8 @@ class GithubProject(models.Model):
4451
active = models.BooleanField(_('Active'), default=False)
4552
json = models.TextField('JSON')
4653

54+
objects = GithubProjectManager()
55+
4756
def __unicode__(self):
4857
return "GitHub Project: %s" % (self.html_url)
4958

@@ -71,6 +80,8 @@ class BitbucketTeam(models.Model):
7180
active = models.BooleanField(_('Active'), default=False)
7281
json = models.TextField('JSON')
7382

83+
objects = BitbucketTeamManager()
84+
7485
def __unicode__(self):
7586
return "Bitbucket Team: %s" % (self.html_url)
7687

@@ -95,5 +106,7 @@ class BitbucketProject(models.Model):
95106
active = models.BooleanField(_('Active'), default=False)
96107
json = models.TextField('JSON')
97108

109+
objects = BitbucketProjectManager()
110+
98111
def __unicode__(self):
99112
return "Bitbucket Project: %s" % (self.html_url)

readthedocs/oauth/utils.py

Lines changed: 10 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from django.conf import settings
66
from requests_oauthlib import OAuth1Session, OAuth2Session
77

8-
from .models import GithubProject, GithubOrganization, BitbucketProject, BitbucketTeam
8+
from .models import GithubProject, GithubOrganization, BitbucketProject
99
from tastyapi import apiv2
1010

1111
log = logging.getLogger(__name__)
@@ -37,45 +37,6 @@ def get_oauth_session(user, provider):
3737
return session or None
3838

3939

40-
def make_github_project(user, org, privacy, repo_json):
41-
log.info('Trying GitHub: %s' % repo_json['full_name'])
42-
if (repo_json['private'] is True and privacy == 'private' or
43-
repo_json['private'] is False and privacy == 'public'):
44-
project, created = GithubProject.objects.get_or_create(
45-
full_name=repo_json['full_name'],
46-
users__pk=user.pk,
47-
)
48-
if project.organization and project.organization != org:
49-
log.debug('Not importing %s because mismatched orgs' % repo_json['name'])
50-
return None
51-
else:
52-
project.organization = org
53-
project.users.add(user)
54-
project.name = repo_json['name']
55-
project.description = repo_json['description']
56-
project.git_url = repo_json['git_url']
57-
project.ssh_url = repo_json['ssh_url']
58-
project.html_url = repo_json['html_url']
59-
project.json = repo_json
60-
project.save()
61-
return project
62-
else:
63-
log.debug('Not importing %s because mismatched type' % repo_json['name'])
64-
65-
66-
def make_github_organization(user, org_json):
67-
org, created = GithubOrganization.objects.get_or_create(
68-
login=org_json.get('login'),
69-
)
70-
org.html_url = org_json.get('html_url')
71-
org.name = org_json.get('name')
72-
org.email = org_json.get('email')
73-
org.json = org_json
74-
org.users.add(user)
75-
org.save()
76-
return org
77-
78-
7940
def get_token_for_project(project, force_local=False):
8041
if not getattr(settings, 'ALLOW_PRIVATE_REPOS', False):
8142
return None
@@ -118,14 +79,13 @@ def github_paginate(session, url):
11879
def import_github(user, sync):
11980
""" Do the actual github import """
12081

121-
repo_type = getattr(settings, 'GITHUB_PRIVACY', 'public')
12282
session = get_oauth_session(user, provider='github')
12383
if sync and session:
12484
# Get user repos
12585
owner_resp = github_paginate(session, 'https://api.github.com/user/repos?per_page=100')
12686
try:
12787
for repo in owner_resp:
128-
make_github_project(user=user, org=None, privacy=repo_type, repo_json=repo)
88+
GithubProject.objects.create_from_api(repo, user=user)
12989
except TypeError, e:
13090
print e
13191

@@ -134,11 +94,13 @@ def import_github(user, sync):
13494
resp = session.get('https://api.github.com/user/orgs')
13595
for org_json in resp.json():
13696
org_resp = session.get('https://api.github.com/orgs/%s' % org_json['login'])
137-
org_obj = make_github_organization(user=user, org_json=org_resp.json())
97+
org_obj = GithubOrganization.objects.create_from_api(
98+
org_resp.json(), user=user)
13899
# Add repos
139100
org_repos_resp = github_paginate(session, 'https://api.github.com/orgs/%s/repos?per_page=100' % org_json['login'])
140101
for repo in org_repos_resp:
141-
make_github_project(user=user, org=org_obj, privacy=repo_type, repo_json=repo)
102+
GithubProject.objects.create_from_api(
103+
repo, user=user, organization=org_obj)
142104
except TypeError, e:
143105
print e
144106

@@ -171,58 +133,31 @@ def bitbucket_paginate(session, url):
171133
return result
172134

173135

174-
def make_bitbucket_project(user, org, privacy, repo_json):
175-
log.info('Trying Bitbucket: %s' % repo_json['full_name'])
176-
if (repo_json['is_private'] is True and privacy == 'private' or
177-
repo_json['is_private'] is False and privacy == 'public'):
178-
project, created = BitbucketProject.objects.get_or_create(
179-
full_name=repo_json['full_name'],
180-
)
181-
if project.organization and project.organization != org:
182-
log.debug('Not importing %s because mismatched orgs' % repo_json['name'])
183-
return None
184-
else:
185-
project.organization = org
186-
project.users.add(user)
187-
project.name = repo_json['name']
188-
project.description = repo_json['description']
189-
project.git_url = repo_json['links']['clone'][0]['href']
190-
project.ssh_url = repo_json['links']['clone'][1]['href']
191-
project.html_url = repo_json['links']['html']['href']
192-
project.vcs = repo_json['scm']
193-
project.json = repo_json
194-
project.save()
195-
return project
196-
else:
197-
log.debug('Not importing %s because mismatched type' % repo_json['name'])
198-
199-
200-
def process_bitbucket_json(user, json, repo_type):
136+
def process_bitbucket_json(user, json):
201137
try:
202138
for page in json:
203139
for repo in page['values']:
204-
make_bitbucket_project(user=user, org=None, privacy=repo_type, repo_json=repo)
140+
BitbucketProject.objects.create_from_api(repo, user=user)
205141
except TypeError, e:
206142
print e
207143

208144

209145
def import_bitbucket(user, sync):
210146
""" Do the actual github import """
211147

212-
repo_type = getattr(settings, 'GITHUB_PRIVACY', 'public')
213148
session = get_oauth_session(user, provider='bitbucket')
214149
if sync and session:
215150
# Get user repos
216151
try:
217152
owner_resp = bitbucket_paginate(session, 'https://bitbucket.org/api/2.0/repositories/{owner}'.format(owner=user.username))
218-
process_bitbucket_json(user, owner_resp, repo_type)
153+
process_bitbucket_json(user, owner_resp)
219154
except TypeError, e:
220155
print e
221156

222157
# Get org repos
223158
resp = session.get('https://bitbucket.org/api/1.0/user/privileges/')
224159
for team in resp.json()['teams'].keys():
225160
org_resp = bitbucket_paginate(session, 'https://bitbucket.org/api/2.0/teams/{team}/repositories'.format(team=team))
226-
process_bitbucket_json(user, org_resp, repo_type)
161+
process_bitbucket_json(user, org_resp)
227162

228163
return session is not None

readthedocs/rtd_tests/tests/test_oauth.py

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
from projects.models import Project
77

8-
from oauth.utils import make_github_project, make_github_organization, import_github
8+
from oauth.utils import import_github
99
from oauth.models import GithubOrganization, GithubProject
1010

1111

@@ -30,7 +30,9 @@ def test_make_github_project_pass(self):
3030
"ssh_url": "",
3131
"html_url": "",
3232
}
33-
github_project = make_github_project(user=self.user, org=self.org, privacy=self.privacy, repo_json=repo_json)
33+
github_project = GithubProject.objects.create_from_api(
34+
repo_json, user=self.user, organization=self.org,
35+
privacy=self.privacy)
3436
self.assertIsInstance(github_project, GithubProject)
3537

3638
def test_make_github_project_fail(self):
@@ -43,7 +45,9 @@ def test_make_github_project_fail(self):
4345
"ssh_url": "",
4446
"html_url": "",
4547
}
46-
github_project = make_github_project(user=self.user, org=self.org, privacy=self.privacy, repo_json=repo_json)
48+
github_project = GithubProject.objects.create_from_api(
49+
repo_json, user=self.user, organization=self.org,
50+
privacy=self.privacy)
4751
self.assertIsNone(github_project)
4852

4953
def test_make_github_organization(self):
@@ -53,14 +57,16 @@ def test_make_github_organization(self):
5357
"email": "",
5458
"login": "",
5559
}
56-
org = make_github_organization(self.user, org_json)
60+
org = GithubOrganization.objects.create_from_api(
61+
org_json, user=self.user)
5762
self.assertIsInstance(org, GithubOrganization)
5863

5964
def test_import_github_with_no_token(self):
6065
github_connected = import_github(self.user, sync=True)
6166
self.assertEqual(github_connected, False)
6267

6368
def test_multiple_users_same_repo(self):
69+
user2 = User.objects.get(pk=2)
6470
repo_json = {
6571
"name": "",
6672
"full_name": "testrepo/multiple",
@@ -70,21 +76,31 @@ def test_multiple_users_same_repo(self):
7076
"ssh_url": "",
7177
"html_url": "",
7278
}
73-
github_project = make_github_project(user=self.user, org=self.org, privacy=self.privacy, repo_json=repo_json)
74-
github_project_2 = make_github_project(user=User.objects.get(pk=2), org=self.org, privacy=self.privacy, repo_json=repo_json)
79+
80+
github_project = GithubProject.objects.create_from_api(
81+
repo_json, user=self.user, organization=self.org,
82+
privacy=self.privacy)
83+
github_project_2 = GithubProject.objects.create_from_api(
84+
repo_json, user=user2, organization=self.org, privacy=self.privacy)
7585
self.assertIsInstance(github_project, GithubProject)
7686
self.assertIsInstance(github_project_2, GithubProject)
7787
self.assertNotEqual(github_project_2, github_project)
7888

79-
github_project_3 = make_github_project(user=self.user, org=self.org, privacy=self.privacy, repo_json=repo_json)
80-
github_project_4 = make_github_project(user=User.objects.get(pk=2), org=self.org, privacy=self.privacy, repo_json=repo_json)
89+
github_project_3 = GithubProject.objects.create_from_api(
90+
repo_json, user=self.user, organization=self.org,
91+
privacy=self.privacy)
92+
github_project_4 = GithubProject.objects.create_from_api(
93+
repo_json, user=user2, organization=self.org, privacy=self.privacy)
8194
self.assertIsInstance(github_project_3, GithubProject)
8295
self.assertIsInstance(github_project_4, GithubProject)
8396
self.assertEqual(github_project, github_project_3)
8497
self.assertEqual(github_project_2, github_project_4)
8598

86-
github_project_5 = make_github_project(user=self.user, org=self.org, privacy=self.privacy, repo_json=repo_json)
87-
github_project_6 = make_github_project(user=User.objects.get(pk=2), org=self.org, privacy=self.privacy, repo_json=repo_json)
99+
github_project_5 = GithubProject.objects.create_from_api(
100+
repo_json, user=self.user, organization=self.org,
101+
privacy=self.privacy)
102+
github_project_6 = GithubProject.objects.create_from_api(
103+
repo_json, user=user2, organization=self.org, privacy=self.privacy)
88104

89105
self.assertEqual(github_project, github_project_5)
90106
self.assertEqual(github_project_2, github_project_6)

0 commit comments

Comments
 (0)