|
9 | 9 | from allauth.socialaccount.models import SocialToken, SocialAccount
|
10 | 10 | from allauth.socialaccount.providers.bitbucket.provider import BitbucketProvider
|
11 | 11 | from allauth.socialaccount.providers.github.provider import GitHubProvider
|
| 12 | +from allauth.socialaccount.providers.gitlab.provider import GitLabProvider |
| 13 | +from allauth.socialaccount.providers.gitlab.views import GitLabOAuth2Adapter |
12 | 14 |
|
13 | 15 | from readthedocs.builds import utils as build_utils
|
14 | 16 | from readthedocs.restapi.client import api
|
@@ -42,6 +44,14 @@ def get_oauth_session(user, provider):
|
42 | 44 | resource_owner_key=token.token,
|
43 | 45 | resource_owner_secret=token.token_secret
|
44 | 46 | )
|
| 47 | + elif provider == GitLabProvider.id: |
| 48 | + session = OAuth2Session( |
| 49 | + client_id=token.app.client_id, |
| 50 | + token={ |
| 51 | + 'access_token': str(token.token), |
| 52 | + 'token_type': 'bearer' |
| 53 | + } |
| 54 | + ) |
45 | 55 |
|
46 | 56 | return session or None
|
47 | 57 |
|
@@ -217,3 +227,59 @@ def import_bitbucket(user, sync):
|
217 | 227 | 'try reconnecting your account')
|
218 | 228 |
|
219 | 229 | return session is not None
|
| 230 | + |
| 231 | +### |
| 232 | +# GitLab |
| 233 | +### |
| 234 | + |
| 235 | +def gitlab_paginate(session, url): |
| 236 | + """Combines results from GitLab pagination |
| 237 | +
|
| 238 | + :param session: requests client instance |
| 239 | + :param url: start url to get the data from. |
| 240 | +
|
| 241 | + """ |
| 242 | + result = [] |
| 243 | + while url: |
| 244 | + r = session.get(url) |
| 245 | + result.extend([r.json()]) |
| 246 | + if 'next' in r.links: |
| 247 | + url = r.links['next']['url'] |
| 248 | + else: |
| 249 | + url = None |
| 250 | + return result |
| 251 | + |
| 252 | + |
| 253 | +def process_gitlab_json(user, json): |
| 254 | + try: |
| 255 | + for page in json: |
| 256 | + for repo in page: |
| 257 | + if repo.get('archived'): |
| 258 | + continue |
| 259 | + RemoteRepository.objects.create_from_gitlab_api(repo, |
| 260 | + user=user) |
| 261 | + except TypeError, e: |
| 262 | + print e |
| 263 | + |
| 264 | + |
| 265 | +def import_gitlab(user, sync): |
| 266 | + """Import from GitLab""" |
| 267 | + session = get_oauth_session(user, provider=GitLabProvider.id) |
| 268 | + try: |
| 269 | + social_account = user.socialaccount_set.get(provider=GitLabProvider.id) |
| 270 | + except SocialAccount.DoesNotExist: |
| 271 | + pass |
| 272 | + if sync and session: |
| 273 | + # Get user repos |
| 274 | + try: |
| 275 | + owner_resp = gitlab_paginate( |
| 276 | + session, '{0}/api/v3/projects'.format( |
| 277 | + GitLabOAuth2Adapter.provider_base_url |
| 278 | + ) |
| 279 | + ) |
| 280 | + process_gitlab_json(user, owner_resp) |
| 281 | + except (TypeError, ValueError): |
| 282 | + raise Exception('Could not sync your GitLab repositories, ' |
| 283 | + 'try reconnecting your account') |
| 284 | + |
| 285 | + return session is not None |
0 commit comments