Commit 8a6b919ab9f6b3ce4c112102863cbfd3b3e1942a

Authored by Lucas Kanashiro
2 parents fb0a796d dd6820bc

Merge branch 'gitlab_plugin' into 'master'

Gitlab plugin

See merge request !94
colab/accounts/migrations/0006_auto_20150828_1719.py 0 → 100644
@@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
  1 +# -*- coding: utf-8 -*-
  2 +from __future__ import unicode_literals
  3 +
  4 +from django.db import models, migrations
  5 +import django.core.validators
  6 +
  7 +
  8 +class Migration(migrations.Migration):
  9 +
  10 + dependencies = [
  11 + ('accounts', '0005_auto_20150312_1454'),
  12 + ]
  13 +
  14 + operations = [
  15 + migrations.AlterField(
  16 + model_name='user',
  17 + name='username',
  18 + field=models.CharField(help_text='Required. 30 characters or fewer. Letters and digits.', unique=True, max_length=30, verbose_name='username', validators=[django.core.validators.RegexValidator('^[\\w.@+-]+$', 'Enter a valid username.', 'invalid')]),
  19 + preserve_default=True,
  20 + ),
  21 + ]
colab/plugins/gitlab/data_importer.py
@@ -9,7 +9,7 @@ from django.db.models.fields import DateTimeField @@ -9,7 +9,7 @@ from django.db.models.fields import DateTimeField
9 from colab.plugins.data import PluginDataImporter 9 from colab.plugins.data import PluginDataImporter
10 10
11 from .models import (GitlabProject, GitlabMergeRequest, 11 from .models import (GitlabProject, GitlabMergeRequest,
12 - GitlabComment, GitlabIssue) 12 + GitlabComment, GitlabIssue, GitlabGroup)
13 13
14 14
15 LOGGER = logging.getLogger('colab.plugin.gitlab') 15 LOGGER = logging.getLogger('colab.plugin.gitlab')
@@ -63,120 +63,82 @@ class GitlabDataImporter(PluginDataImporter): @@ -63,120 +63,82 @@ class GitlabDataImporter(PluginDataImporter):
63 63
64 return _object 64 return _object
65 65
66 - def fetch_projects(self): 66 + def fetch(self, url, gitlab_class):
67 page = 1 67 page = 1
68 - projects = [] 68 + obj_list = []
69 69
70 while True: 70 while True:
71 - json_data = self.get_json_data('/api/v3/projects/all', page) 71 + json_data = self.get_json_data(url, page)
72 page = page + 1 72 page = page + 1
73 73
74 if not len(json_data): 74 if not len(json_data):
75 break 75 break
76 76
77 for element in json_data: 77 for element in json_data:
78 - project = GitlabProject()  
79 - self.fill_object_data(element, project)  
80 - projects.append(project) 78 + obj = gitlab_class()
  79 + self.fill_object_data(element, obj)
  80 + obj_list.append(obj)
81 81
82 - return projects 82 + return obj_list
83 83
84 - def fetch_merge_request(self, projects):  
85 - all_merge_request = [] 84 + def fetch_comments(self, url, parent_class, issue_comment):
  85 + all_comments = []
  86 + all_parent_objects = parent_class.objects.all()
86 87
87 - for project in projects: 88 + for parent_obj in all_parent_objects:
88 page = 1 89 page = 1
89 while True: 90 while True:
90 - url = '/api/v3/projects/{}/merge_requests'.format(project.id)  
91 - json_data_mr = self.get_json_data(url, page) 91 + formated_url = url.format(parent_obj.project_id, parent_obj.id)
  92 + json_data = self.get_json_data(formated_url, page)
92 page = page + 1 93 page = page + 1
93 94
94 - if len(json_data_mr) == 0: 95 + if len(json_data) == 0:
95 break 96 break
96 97
97 - for element in json_data_mr:  
98 - single_merge_request = GitlabMergeRequest()  
99 - self.fill_object_data(element, single_merge_request)  
100 - all_merge_request.append(single_merge_request)  
101 -  
102 - return all_merge_request 98 + for element in json_data:
  99 + single_comment = GitlabComment()
  100 + self.fill_object_data(element, single_comment)
  101 + single_comment.project = parent_obj.project
  102 + single_comment.issue_comment = issue_comment
  103 + single_comment.parent_id = parent_obj.id
  104 + all_comments.append(single_comment)
103 105
104 - def fetch_issue(self, projects):  
105 - all_issues = [] 106 + return all_comments
106 107
107 - for project in projects:  
108 - page = 1  
109 - while True:  
110 - url = '/api/v3/projects/{}/issues'.format(project.id)  
111 - json_data_issue = self.get_json_data(url, page)  
112 - page = page + 1 108 + def fetch_projects(self):
  109 + return self.fetch('/api/v3/projects/all', GitlabProject)
113 110
114 - if len(json_data_issue) == 0:  
115 - break 111 + def fetch_groups(self):
  112 + return self.fetch('/api/v3/groups', GitlabGroup)
116 113
117 - for element in json_data_issue:  
118 - single_issue = GitlabIssue()  
119 - self.fill_object_data(element, single_issue)  
120 - all_issues.append(single_issue) 114 + def fetch_merge_request(self, projects):
  115 + merge_requests = []
  116 + for project in projects:
  117 + url = '/api/v3/projects/{}/merge_requests'.format(project.id)
  118 + merge_requests.extend(self.fetch(url, GitlabMergeRequest))
  119 + return merge_requests
121 120
122 - return all_issues 121 + def fetch_issue(self, projects):
  122 + issues = []
  123 + for project in projects:
  124 + url = '/api/v3/projects/{}/issues'.format(project.id)
  125 + issues.extend(self.fetch(url, GitlabIssue))
  126 + return issues
123 127
124 - def fetch_comments(self): 128 + def fetch_all_comments(self):
125 all_comments = [] 129 all_comments = []
126 - all_comments.extend(self.fetch_comments_MR()) 130 + all_comments.extend(self.fetch_comments_mr())
127 all_comments.extend(self.fetch_comments_issues()) 131 all_comments.extend(self.fetch_comments_issues())
128 132
129 return all_comments 133 return all_comments
130 134
131 - def fetch_comments_MR(self):  
132 - all_comments = []  
133 - all_merge_requests = GitlabMergeRequest.objects.all()  
134 -  
135 - for merge_request in all_merge_requests:  
136 - page = 1  
137 - while True:  
138 - url = '/api/v3/projects/{}/merge_requests/{}/notes'.format(  
139 - merge_request.project_id, merge_request.id)  
140 - json_data_mr = self.get_json_data(url, page)  
141 - page = page + 1  
142 -  
143 - if len(json_data_mr) == 0:  
144 - break  
145 -  
146 - for element in json_data_mr:  
147 - single_comment = GitlabComment()  
148 - self.fill_object_data(element, single_comment)  
149 - single_comment.project = merge_request.project  
150 - single_comment.issue_comment = False  
151 - single_comment.parent_id = merge_request.id  
152 - all_comments.append(single_comment)  
153 -  
154 - return all_comments 135 + def fetch_comments_mr(self):
  136 + url = '/api/v3/projects/{}/merge_requests/{}/notes'
  137 + return self.fetch_comments(url, GitlabMergeRequest, False)
155 138
156 def fetch_comments_issues(self): 139 def fetch_comments_issues(self):
157 - all_comments = []  
158 - all_issues = GitlabIssue.objects.all()  
159 -  
160 - for issue in all_issues:  
161 - page = 1  
162 - while True:  
163 - url = '/api/v3/projects/{}/issues/{}/notes'.format(  
164 - issue.project_id, issue.id)  
165 - json_data_mr = self.get_json_data(url, page)  
166 - page = page + 1  
167 -  
168 - if len(json_data_mr) == 0:  
169 - break  
170 -  
171 - for element in json_data_mr:  
172 - single_comment = GitlabComment()  
173 - self.fill_object_data(element, single_comment)  
174 - single_comment.project = issue.project  
175 - single_comment.issue_comment = True  
176 - single_comment.parent_id = issue.id  
177 - all_comments.append(single_comment)  
178 -  
179 - return all_comments 140 + url = '/api/v3/projects/{}/issues/{}/notes'
  141 + return self.fetch_comments(url, GitlabIssue, True)
180 142
181 143
182 class GitlabProjectImporter(GitlabDataImporter): 144 class GitlabProjectImporter(GitlabDataImporter):
@@ -212,6 +174,6 @@ class GitlabCommentImporter(GitlabDataImporter): @@ -212,6 +174,6 @@ class GitlabCommentImporter(GitlabDataImporter):
212 174
213 def fetch_data(self): 175 def fetch_data(self):
214 LOGGER.info("Importing Comments") 176 LOGGER.info("Importing Comments")
215 - comments_list = self.fetch_comments() 177 + comments_list = self.fetch_all_comments()
216 for datum in comments_list: 178 for datum in comments_list:
217 datum.save() 179 datum.save()
colab/plugins/gitlab/fixtures/__init__.py 0 → 100644
colab/plugins/gitlab/fixtures/gitlab_associations.json 0 → 100644
@@ -0,0 +1,100 @@ @@ -0,0 +1,100 @@
  1 +[
  2 +{
  3 + "fields": {
  4 + "last_name": "Administrator",
  5 + "webpage": "",
  6 + "twitter": "",
  7 + "is_staff": true,
  8 + "user_permissions": [],
  9 + "date_joined": "2015-01-28T12:34:58.770Z",
  10 + "google_talk": "",
  11 + "first_name": "Admin",
  12 + "is_superuser": true,
  13 + "last_login": "2015-08-24T14:33:28.802Z",
  14 + "verification_hash": null,
  15 + "role": "",
  16 + "email": "admin@mail.com",
  17 + "username": "admin",
  18 + "bio": "",
  19 + "needs_update": true,
  20 + "is_active": true,
  21 + "facebook": "",
  22 + "groups": [],
  23 + "password": "pbkdf2_sha256$15000$sWnvfYpB8ec4$7dEFg6vSSGPnpEmfRelJ12zkiwacGx9aXx8/8ZFWBSI=",
  24 + "institution": "",
  25 + "github": "",
  26 + "modified": "2015-01-28T12:45:27.375Z"
  27 + },
  28 + "model": "accounts.user",
  29 + "pk": 1
  30 +},
  31 +{
  32 + "fields": {
  33 + "last_name": "user",
  34 + "webpage": null,
  35 + "twitter": null,
  36 + "is_staff": false,
  37 + "user_permissions": [],
  38 + "date_joined": "2015-08-24T14:33:55.827Z",
  39 + "google_talk": null,
  40 + "first_name": "user",
  41 + "is_superuser": false,
  42 + "last_login": "2015-08-24T14:33:55.827Z",
  43 + "verification_hash": null,
  44 + "role": null,
  45 + "email": "user@teste.com",
  46 + "username": "user",
  47 + "bio": null,
  48 + "needs_update": true,
  49 + "is_active": true,
  50 + "facebook": null,
  51 + "groups": [],
  52 + "password": "pbkdf2_sha256$15000$9ew6EvFvAIhI$147annuMjzt7em5IRh+3k7wcl7rZ0xjBPSmbUZDdxFo=",
  53 + "institution": null,
  54 + "github": null,
  55 + "modified": "2015-08-24T14:33:55.893Z"
  56 + },
  57 + "model": "accounts.user",
  58 + "pk": 2
  59 +},
  60 +{
  61 + "fields": {
  62 + "last_activity_at": "2015-06-08T19:28:27.148Z",
  63 + "description": "Colab source code",
  64 + "name_with_namespace": "Software Publico / Colab",
  65 + "created_at": "2014-09-26T14:58:52.491Z",
  66 + "path_with_namespace": "softwarepublico/colab",
  67 + "public": true,
  68 + "name": "Colab"
  69 + },
  70 + "model": "gitlab.gitlabproject",
  71 + "pk": 14
  72 +},
  73 +{
  74 + "fields": {
  75 + "target_branch": "master",
  76 + "description": "",
  77 + "source_branch": "settings_fix",
  78 + "created_at": "2014-10-24T12:05:55.659Z",
  79 + "title": "Settings fix",
  80 + "project": 14,
  81 + "iid": 1,
  82 + "state": "merged",
  83 + "user": null
  84 + },
  85 + "model": "gitlab.gitlabmergerequest",
  86 + "pk": 7
  87 +},
  88 +{
  89 + "fields": {
  90 + "description": "Remove the main SPB logo from the homepage",
  91 + "title": "Remove the SPB central logo",
  92 + "created_at": "2014-10-07T17:40:27.625Z",
  93 + "project": 14,
  94 + "state": "closed",
  95 + "user": null
  96 + },
  97 + "model": "gitlab.gitlabissue",
  98 + "pk": 2
  99 +}
  100 +]
0 \ No newline at end of file 101 \ No newline at end of file
colab/plugins/gitlab/fixtures/test_gitlab_data.json 0 → 100644
@@ -0,0 +1,146 @@ @@ -0,0 +1,146 @@
  1 +[
  2 +{
  3 + "fields": {
  4 + "last_name": "COLAB",
  5 + "webpage": null,
  6 + "twitter": "usertestcolab",
  7 + "is_staff": false,
  8 + "user_permissions": [],
  9 + "date_joined": "2015-08-28T18:00:59.753Z",
  10 + "google_talk": null,
  11 + "first_name": "USERtestCoLaB",
  12 + "is_superuser": false,
  13 + "last_login": "2015-08-28T18:00:59.753Z",
  14 + "verification_hash": null,
  15 + "role": null,
  16 + "email": "usertest@colab.com.br",
  17 + "username": "usertestcolab",
  18 + "bio": null,
  19 + "needs_update": true,
  20 + "is_active": true,
  21 + "facebook": "usertestcolab",
  22 + "groups": [],
  23 + "password": "pbkdf2_sha256$15000$unxhDDCB1vsw$Esdx3tQ2ayPW08/SImQzbBeRiK8Hoa6fBZhw3dMQga8=",
  24 + "institution": null,
  25 + "github": null,
  26 + "modified": "2015-08-28T18:00:59.996Z"
  27 + },
  28 + "model": "accounts.user",
  29 + "pk": 1
  30 +},
  31 +{
  32 + "fields": {
  33 + "last_activity_at": "2015-08-28T18:01:28.469Z",
  34 + "description": "",
  35 + "name_with_namespace": "Software Public / Colab",
  36 + "created_at": "2015-08-28T18:01:28.467Z",
  37 + "path_with_namespace": "softwarepublico/colab",
  38 + "public": true,
  39 + "name": "colab"
  40 + },
  41 + "model": "gitlab.gitlabproject",
  42 + "pk": 1
  43 +},
  44 +{
  45 + "fields": {
  46 + "last_activity_at": "2015-08-28T18:01:28.491Z",
  47 + "description": "",
  48 + "name_with_namespace": "Software Public / ColabInc",
  49 + "created_at": "2015-08-28T18:01:28.489Z",
  50 + "path_with_namespace": "softwarepublico/colabinc",
  51 + "public": true,
  52 + "name": "colabinc"
  53 + },
  54 + "model": "gitlab.gitlabproject",
  55 + "pk": 2
  56 +},
  57 +{
  58 + "fields": {
  59 + "path": "softwarepublico",
  60 + "name": "Software Public",
  61 + "owner_id": 1
  62 + },
  63 + "model": "gitlab.gitlabgroup",
  64 + "pk": 1
  65 +},
  66 +{
  67 + "fields": {
  68 + "target_branch": "",
  69 + "description": "Merge request for plugin support",
  70 + "source_branch": "",
  71 + "created_at": "2015-08-28T18:01:28.512Z",
  72 + "title": "Include plugin support",
  73 + "project": 1,
  74 + "iid": 1,
  75 + "state": "Closed",
  76 + "user": 1
  77 + },
  78 + "model": "gitlab.gitlabmergerequest",
  79 + "pk": 1
  80 +},
  81 +{
  82 + "fields": {
  83 + "target_branch": "",
  84 + "description": "Merge request for test support",
  85 + "source_branch": "",
  86 + "created_at": "2015-08-28T18:01:28.561Z",
  87 + "title": "Include test support",
  88 + "project": 2,
  89 + "iid": 1,
  90 + "state": "Closed",
  91 + "user": 1
  92 + },
  93 + "model": "gitlab.gitlabmergerequest",
  94 + "pk": 2
  95 +},
  96 +{
  97 + "fields": {
  98 + "description": "Issue reported to colab",
  99 + "title": "Issue for colab",
  100 + "created_at": "2015-08-28T18:01:28.590Z",
  101 + "project": 1,
  102 + "iid": 1,
  103 + "state": "Open",
  104 + "user": 1
  105 + },
  106 + "model": "gitlab.gitlabissue",
  107 + "pk": 1
  108 +},
  109 +{
  110 + "fields": {
  111 + "description": "Issue reported to colab",
  112 + "title": "Issue for colab",
  113 + "created_at": "2015-08-28T18:01:28.628Z",
  114 + "project": 2,
  115 + "iid": 1,
  116 + "state": "Open",
  117 + "user": 1
  118 + },
  119 + "model": "gitlab.gitlabissue",
  120 + "pk": 2
  121 +},
  122 +{
  123 + "fields": {
  124 + "body": "Comment to merge request",
  125 + "created_at": "2015-08-28T18:01:28.663Z",
  126 + "issue_comment": false,
  127 + "project": 1,
  128 + "parent_id": 1,
  129 + "user": 1
  130 + },
  131 + "model": "gitlab.gitlabcomment",
  132 + "pk": 1
  133 +},
  134 +{
  135 + "fields": {
  136 + "body": "Comment to issue",
  137 + "created_at": "2015-08-28T18:01:28.693Z",
  138 + "issue_comment": true,
  139 + "project": 1,
  140 + "parent_id": 1,
  141 + "user": 1
  142 + },
  143 + "model": "gitlab.gitlabcomment",
  144 + "pk": 2
  145 +}
  146 +]
colab/plugins/gitlab/migrations/0001_initial.py
@@ -2,15 +2,82 @@ @@ -2,15 +2,82 @@
2 from __future__ import unicode_literals 2 from __future__ import unicode_literals
3 3
4 from django.db import models, migrations 4 from django.db import models, migrations
  5 +import django.db.models.deletion
  6 +import hitcounter.models
  7 +from django.conf import settings
5 8
6 9
7 class Migration(migrations.Migration): 10 class Migration(migrations.Migration):
8 11
9 dependencies = [ 12 dependencies = [
  13 + migrations.swappable_dependency(settings.AUTH_USER_MODEL),
10 ] 14 ]
11 15
12 operations = [ 16 operations = [
13 migrations.CreateModel( 17 migrations.CreateModel(
  18 + name='GitlabComment',
  19 + fields=[
  20 + ('id', models.IntegerField(serialize=False, primary_key=True)),
  21 + ('body', models.TextField()),
  22 + ('created_at', models.DateTimeField(null=True, blank=True)),
  23 + ('issue_comment', models.BooleanField(default=True)),
  24 + ('parent_id', models.IntegerField(null=True)),
  25 + ],
  26 + options={
  27 + 'verbose_name': 'Gitlab Comments',
  28 + 'verbose_name_plural': 'Gitlab Comments',
  29 + },
  30 + bases=(models.Model,),
  31 + ),
  32 + migrations.CreateModel(
  33 + name='GitlabGroup',
  34 + fields=[
  35 + ('id', models.IntegerField(serialize=False, primary_key=True)),
  36 + ('name', models.CharField(max_length=100)),
  37 + ('path', models.CharField(max_length=100)),
  38 + ('owner_id', models.IntegerField(null=True)),
  39 + ],
  40 + options={
  41 + 'verbose_name': 'Gitlab Group',
  42 + 'verbose_name_plural': 'Gitlab Groups',
  43 + },
  44 + bases=(models.Model,),
  45 + ),
  46 + migrations.CreateModel(
  47 + name='GitlabIssue',
  48 + fields=[
  49 + ('id', models.IntegerField(serialize=False, primary_key=True)),
  50 + ('iid', models.IntegerField(null=True)),
  51 + ('title', models.TextField()),
  52 + ('description', models.TextField()),
  53 + ('state', models.TextField()),
  54 + ('created_at', models.DateTimeField(null=True, blank=True)),
  55 + ],
  56 + options={
  57 + 'verbose_name': 'Gitlab Issue',
  58 + 'verbose_name_plural': 'Gitlab Issues',
  59 + },
  60 + bases=(models.Model,),
  61 + ),
  62 + migrations.CreateModel(
  63 + name='GitlabMergeRequest',
  64 + fields=[
  65 + ('id', models.IntegerField(serialize=False, primary_key=True)),
  66 + ('iid', models.IntegerField(null=True)),
  67 + ('target_branch', models.TextField()),
  68 + ('source_branch', models.TextField()),
  69 + ('description', models.TextField()),
  70 + ('title', models.TextField()),
  71 + ('state', models.TextField()),
  72 + ('created_at', models.DateTimeField(null=True, blank=True)),
  73 + ],
  74 + options={
  75 + 'verbose_name': 'Gitlab Merge Request',
  76 + 'verbose_name_plural': 'Gitlab Merge Requests',
  77 + },
  78 + bases=(models.Model,),
  79 + ),
  80 + migrations.CreateModel(
14 name='GitlabProject', 81 name='GitlabProject',
15 fields=[ 82 fields=[
16 ('id', models.IntegerField(serialize=False, primary_key=True)), 83 ('id', models.IntegerField(serialize=False, primary_key=True)),
@@ -20,9 +87,48 @@ class Migration(migrations.Migration): @@ -20,9 +87,48 @@ class Migration(migrations.Migration):
20 ('name_with_namespace', models.TextField()), 87 ('name_with_namespace', models.TextField()),
21 ('created_at', models.DateTimeField(blank=True)), 88 ('created_at', models.DateTimeField(blank=True)),
22 ('last_activity_at', models.DateTimeField(blank=True)), 89 ('last_activity_at', models.DateTimeField(blank=True)),
  90 + ('path_with_namespace', models.TextField(null=True, blank=True)),
23 ], 91 ],
24 options={ 92 options={
  93 + 'verbose_name': 'Gitlab Project',
  94 + 'verbose_name_plural': 'Gitlab Projects',
25 }, 95 },
26 - bases=(models.Model,), 96 + bases=(models.Model, hitcounter.models.HitCounterModelMixin),
  97 + ),
  98 + migrations.AddField(
  99 + model_name='gitlabmergerequest',
  100 + name='project',
  101 + field=models.ForeignKey(on_delete=django.db.models.deletion.SET_NULL, to='gitlab.GitlabProject', null=True),
  102 + preserve_default=True,
  103 + ),
  104 + migrations.AddField(
  105 + model_name='gitlabmergerequest',
  106 + name='user',
  107 + field=models.ForeignKey(on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, null=True),
  108 + preserve_default=True,
  109 + ),
  110 + migrations.AddField(
  111 + model_name='gitlabissue',
  112 + name='project',
  113 + field=models.ForeignKey(on_delete=django.db.models.deletion.SET_NULL, to='gitlab.GitlabProject', null=True),
  114 + preserve_default=True,
  115 + ),
  116 + migrations.AddField(
  117 + model_name='gitlabissue',
  118 + name='user',
  119 + field=models.ForeignKey(on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, null=True),
  120 + preserve_default=True,
  121 + ),
  122 + migrations.AddField(
  123 + model_name='gitlabcomment',
  124 + name='project',
  125 + field=models.ForeignKey(on_delete=django.db.models.deletion.SET_NULL, to='gitlab.GitlabProject', null=True),
  126 + preserve_default=True,
  127 + ),
  128 + migrations.AddField(
  129 + model_name='gitlabcomment',
  130 + name='user',
  131 + field=models.ForeignKey(on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, null=True),
  132 + preserve_default=True,
27 ), 133 ),
28 ] 134 ]
colab/plugins/gitlab/migrations/0002_auto_20150205_1220.py
@@ -1,69 +0,0 @@ @@ -1,69 +0,0 @@
1 -# -*- coding: utf-8 -*-  
2 -from __future__ import unicode_literals  
3 -  
4 -from django.db import models, migrations  
5 -import django.db.models.deletion  
6 -from django.conf import settings  
7 -  
8 -  
9 -class Migration(migrations.Migration):  
10 -  
11 - dependencies = [  
12 - migrations.swappable_dependency(settings.AUTH_USER_MODEL),  
13 - ('gitlab', '0001_initial'),  
14 - ]  
15 -  
16 - operations = [  
17 - migrations.CreateModel(  
18 - name='GitlabComment',  
19 - fields=[  
20 - ('id', models.IntegerField(serialize=False, primary_key=True)),  
21 - ('body', models.TextField()),  
22 - ('created_at', models.DateTimeField(blank=True)),  
23 - ('user', models.ForeignKey(on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, null=True)),  
24 - ],  
25 - options={  
26 - 'verbose_name': 'Gitlab Comments',  
27 - 'verbose_name_plural': 'Gitlab Comments',  
28 - },  
29 - bases=(models.Model,),  
30 - ),  
31 - migrations.CreateModel(  
32 - name='GitlabIssue',  
33 - fields=[  
34 - ('id', models.IntegerField(serialize=False, primary_key=True)),  
35 - ('title', models.TextField()),  
36 - ('description', models.TextField()),  
37 - ('state', models.TextField()),  
38 - ('project', models.ForeignKey(on_delete=django.db.models.deletion.SET_NULL, to='gitlab.GitlabProject', null=True)),  
39 - ('user', models.ForeignKey(on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, null=True)),  
40 - ],  
41 - options={  
42 - 'verbose_name': 'Gitlab Collaboration',  
43 - 'verbose_name_plural': 'Gitlab Collaborations',  
44 - },  
45 - bases=(models.Model,),  
46 - ),  
47 - migrations.CreateModel(  
48 - name='GitlabMergeRequest',  
49 - fields=[  
50 - ('id', models.IntegerField(serialize=False, primary_key=True)),  
51 - ('target_branch', models.TextField()),  
52 - ('source_branch', models.TextField()),  
53 - ('description', models.TextField()),  
54 - ('title', models.TextField()),  
55 - ('state', models.TextField()),  
56 - ('project', models.ForeignKey(on_delete=django.db.models.deletion.SET_NULL, to='gitlab.GitlabProject', null=True)),  
57 - ('user', models.ForeignKey(on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, null=True)),  
58 - ],  
59 - options={  
60 - 'verbose_name': 'Gitlab Merge Request',  
61 - 'verbose_name_plural': 'Gitlab Merge Requests',  
62 - },  
63 - bases=(models.Model,),  
64 - ),  
65 - migrations.AlterModelOptions(  
66 - name='gitlabproject',  
67 - options={'verbose_name': 'Gitlab Project', 'verbose_name_plural': 'Gitlab Projects'},  
68 - ),  
69 - ]  
colab/plugins/gitlab/migrations/0003_auto_20150211_1203.py
@@ -1,61 +0,0 @@ @@ -1,61 +0,0 @@
1 -# -*- coding: utf-8 -*-  
2 -from __future__ import unicode_literals  
3 -  
4 -from django.db import models, migrations  
5 -import django.db.models.deletion  
6 -  
7 -  
8 -class Migration(migrations.Migration):  
9 -  
10 - dependencies = [  
11 - ('gitlab', '0002_auto_20150205_1220'),  
12 - ]  
13 -  
14 - operations = [  
15 - migrations.AlterModelOptions(  
16 - name='gitlabissue',  
17 - options={'verbose_name': 'Gitlab Issue', 'verbose_name_plural': 'Gitlab Issues'},  
18 - ),  
19 - migrations.AddField(  
20 - model_name='gitlabcomment',  
21 - name='issue_comment',  
22 - field=models.BooleanField(default=True),  
23 - preserve_default=True,  
24 - ),  
25 - migrations.AddField(  
26 - model_name='gitlabcomment',  
27 - name='parent_id',  
28 - field=models.IntegerField(null=True),  
29 - preserve_default=True,  
30 - ),  
31 - migrations.AddField(  
32 - model_name='gitlabcomment',  
33 - name='project',  
34 - field=models.ForeignKey(on_delete=django.db.models.deletion.SET_NULL, to='gitlab.GitlabProject', null=True),  
35 - preserve_default=True,  
36 - ),  
37 - migrations.AddField(  
38 - model_name='gitlabissue',  
39 - name='created_at',  
40 - field=models.DateTimeField(null=True, blank=True),  
41 - preserve_default=True,  
42 - ),  
43 - migrations.AddField(  
44 - model_name='gitlabmergerequest',  
45 - name='created_at',  
46 - field=models.DateTimeField(null=True, blank=True),  
47 - preserve_default=True,  
48 - ),  
49 - migrations.AddField(  
50 - model_name='gitlabproject',  
51 - name='path_with_namespace',  
52 - field=models.TextField(null=True, blank=True),  
53 - preserve_default=True,  
54 - ),  
55 - migrations.AlterField(  
56 - model_name='gitlabcomment',  
57 - name='created_at',  
58 - field=models.DateTimeField(null=True, blank=True),  
59 - preserve_default=True,  
60 - ),  
61 - ]  
colab/plugins/gitlab/migrations/0004_auto_20150630_1149.py
@@ -1,26 +0,0 @@ @@ -1,26 +0,0 @@
1 -# -*- coding: utf-8 -*-  
2 -from __future__ import unicode_literals  
3 -  
4 -from django.db import models, migrations  
5 -  
6 -  
7 -class Migration(migrations.Migration):  
8 -  
9 - dependencies = [  
10 - ('gitlab', '0003_auto_20150211_1203'),  
11 - ]  
12 -  
13 - operations = [  
14 - migrations.AddField(  
15 - model_name='gitlabcomment',  
16 - name='iid',  
17 - field=models.IntegerField(null=True),  
18 - preserve_default=True,  
19 - ),  
20 - migrations.AddField(  
21 - model_name='gitlabmergerequest',  
22 - name='iid',  
23 - field=models.IntegerField(null=True),  
24 - preserve_default=True,  
25 - ),  
26 - ]  
colab/plugins/gitlab/migrations/0005_auto_20150806_1230.py
@@ -1,24 +0,0 @@ @@ -1,24 +0,0 @@
1 -# -*- coding: utf-8 -*-  
2 -from __future__ import unicode_literals  
3 -  
4 -from django.db import models, migrations  
5 -  
6 -  
7 -class Migration(migrations.Migration):  
8 -  
9 - dependencies = [  
10 - ('gitlab', '0004_auto_20150630_1149'),  
11 - ]  
12 -  
13 - operations = [  
14 - migrations.RemoveField(  
15 - model_name='gitlabcomment',  
16 - name='iid',  
17 - ),  
18 - migrations.AddField(  
19 - model_name='gitlabissue',  
20 - name='iid',  
21 - field=models.IntegerField(null=True),  
22 - preserve_default=True,  
23 - ),  
24 - ]  
colab/plugins/gitlab/models.py
@@ -16,6 +16,10 @@ class GitlabProject(models.Model, HitCounterModelMixin): @@ -16,6 +16,10 @@ class GitlabProject(models.Model, HitCounterModelMixin):
16 path_with_namespace = models.TextField(blank=True, null=True) 16 path_with_namespace = models.TextField(blank=True, null=True)
17 17
18 @property 18 @property
  19 + def namespace(self):
  20 + return self.path_with_namespace.split('/')[0]
  21 +
  22 + @property
19 def url(self): 23 def url(self):
20 return u'/gitlab/{}'.format(self.path_with_namespace) 24 return u'/gitlab/{}'.format(self.path_with_namespace)
21 25
@@ -24,6 +28,33 @@ class GitlabProject(models.Model, HitCounterModelMixin): @@ -24,6 +28,33 @@ class GitlabProject(models.Model, HitCounterModelMixin):
24 verbose_name_plural = _('Gitlab Projects') 28 verbose_name_plural = _('Gitlab Projects')
25 29
26 30
  31 +class GitlabGroup(models.Model):
  32 + id = models.IntegerField(primary_key=True)
  33 + name = models.CharField(max_length=100)
  34 + path = models.CharField(max_length=100)
  35 + owner_id = models.IntegerField(null=True)
  36 +
  37 + def __unicode__(self):
  38 + return u'{}'.format(self.path)
  39 +
  40 + @property
  41 + def projects(self):
  42 + projects = GitlabProject.objects.all()
  43 + result = list()
  44 + for project in projects:
  45 + if self.path in project.namespace:
  46 + result.append(project)
  47 + return result
  48 +
  49 + @property
  50 + def url(self):
  51 + return u'/gitlab/groups/{}'.format(self.path)
  52 +
  53 + class Meta:
  54 + verbose_name = _('Gitlab Group')
  55 + verbose_name_plural = _('Gitlab Groups')
  56 +
  57 +
27 class GitlabMergeRequest(Collaboration): 58 class GitlabMergeRequest(Collaboration):
28 59
29 id = models.IntegerField(primary_key=True) 60 id = models.IntegerField(primary_key=True)
colab/plugins/gitlab/tests/data.py 0 → 100644
@@ -0,0 +1,98 @@ @@ -0,0 +1,98 @@
  1 +colab_apps = {'gitlab':
  2 + {'menu_title': None,
  3 + 'private_token': 'token',
  4 + 'upstream': 'localhost',
  5 + 'urls':
  6 + {'include': 'colab.plugins.gitlab.urls',
  7 + 'namespace': 'gitlab',
  8 + 'prefix': 'gitlab/'}}}
  9 +
  10 +projects_json = [{"id": 32,
  11 + "description": "Test Gitlab",
  12 + "default_branch": "master",
  13 + "public": True,
  14 + "archived": False,
  15 + "visibility_level": 20,
  16 + "ssh_url_to_repo": "git@localhost/gitlabhq.git",
  17 + "http_url_to_repo": "localhost/gitlabhq.git",
  18 + "web_url": "localhost/gitlabhq",
  19 + "name": "Gitlab",
  20 + "name_with_namespace": "Test / Gitlab",
  21 + "path": "gitlabhq"}]
  22 +
  23 +groups_json = [{"id": 23,
  24 + "name": "Group 1",
  25 + "path": "group-1",
  26 + "owner_id": None},
  27 + {"id": 27,
  28 + "name": "Group 2",
  29 + "path": "group-2",
  30 + "owner_id": None}]
  31 +
  32 +merge_json = [{"id": 7,
  33 + "iid": 1,
  34 + "project_id": 14,
  35 + "title": "Merge Title",
  36 + "description": "description",
  37 + "state": "merged",
  38 + "created_at": "2014-10-24T12:05:55.659Z",
  39 + "updated_at": "2014-10-24T12:06:15.572Z",
  40 + "target_branch": "master",
  41 + "source_branch": "settings_fix",
  42 + "upvotes": 0,
  43 + "downvotes": 0,
  44 + "author": {"name": "user",
  45 + "username": "user",
  46 + "id": 8,
  47 + "state": "active",
  48 + "avatar_url": "localhost"},
  49 + "assignee": {"name": "user",
  50 + "username": "user",
  51 + "id": 8,
  52 + "state": "active",
  53 + "avatar_url": "localhost"},
  54 + "source_project_id": 14,
  55 + "target_project_id": 14,
  56 + "labels": [],
  57 + "milestone": None}]
  58 +
  59 +issues_json = [{"id": 8,
  60 + "iid": 1,
  61 + "project_id": 32,
  62 + "title": "title",
  63 + "description": "description",
  64 + "state": "opened",
  65 + "created_at": "2014-10-11T16:25:37.548Z",
  66 + "updated_at": "2014-10-11T16:25:37.548Z",
  67 + "labels": [],
  68 + "milestone": None,
  69 + "assignee": {"name": "name",
  70 + "username": "username",
  71 + "id": 2,
  72 + "state": "active",
  73 + "avatar_url": "avatar_url"},
  74 + "author": {"name": "name",
  75 + "username": "user",
  76 + "id": 2,
  77 + "state": "active",
  78 + "avatar_url": "avatar_url"}}]
  79 +
  80 +comment_mr_json = [{"id": 11,
  81 + "body": "message body",
  82 + "attachment": None,
  83 + "author": {"name": "user",
  84 + "username": "user",
  85 + "id": 8,
  86 + "state": "active",
  87 + "avatar_url": "avatar_url"},
  88 + "created_at": "2014-10-25T14:43:54.863Z"}]
  89 +
  90 +comment_issue_json = [{"id": 447,
  91 + "body": "message body",
  92 + "attachment": None,
  93 + "author": {"name": "user",
  94 + "username": "user",
  95 + "state": "active",
  96 + "id": 8,
  97 + "avatar_url": "avatar_url"},
  98 + "created_at": "2015-03-16T17:34:07.715Z"}]
colab/plugins/gitlab/tests/test_data_importer.py 0 → 100644
@@ -0,0 +1,97 @@ @@ -0,0 +1,97 @@
  1 +from django.test import TestCase
  2 +from django.test.utils import override_settings
  3 +from ..data_importer import GitlabDataImporter
  4 +from ..models import GitlabProject, GitlabIssue
  5 +from mock import patch
  6 +import data
  7 +from dateutil.parser import parse
  8 +
  9 +
  10 +class GitlabDataImporterTest(TestCase):
  11 +
  12 + fixtures = ["gitlab_associations"]
  13 +
  14 + @override_settings(COLAB_APPS=data.colab_apps)
  15 + def setUp(self):
  16 + self.api = GitlabDataImporter()
  17 +
  18 + def test_resquest_url(self):
  19 + url = self.api.get_request_url('/gitlab/test/')
  20 + expected = 'localhost/gitlab/test/?private_token=token'
  21 + self.assertEqual(url, expected)
  22 +
  23 + def test_resquest_url_with_params(self):
  24 + url = self.api.get_request_url('/gitlab/test/', param='param')
  25 + expected = 'localhost/gitlab/test/?private_token=token&param=param'
  26 + self.assertEqual(url, expected)
  27 +
  28 + @patch.object(GitlabDataImporter, 'get_json_data')
  29 + def test_fetch_projects(self, mock_json):
  30 + mock_json.side_effect = [data.projects_json, []]
  31 +
  32 + projects = self.api.fetch_projects()
  33 + self.assertEqual(len(projects), 1)
  34 +
  35 + self.assertEqual(projects[0].description, "Test Gitlab")
  36 + self.assertEqual(projects[0].public, True)
  37 +
  38 + @patch.object(GitlabDataImporter, 'get_json_data')
  39 + def test_fetch_groups(self, mock_json):
  40 + mock_json.side_effect = [data.groups_json, []]
  41 +
  42 + groups = self.api.fetch_groups()
  43 + self.assertEqual(len(groups), 2)
  44 + self.assertEqual(groups[0].name, "Group 1")
  45 + self.assertEqual(groups[1].name, "Group 2")
  46 +
  47 + self.assertEqual(groups[0].path, "group-1")
  48 + self.assertEqual(groups[1].path, "group-2")
  49 +
  50 + @patch.object(GitlabDataImporter, 'get_json_data')
  51 + def test_fetch_merge(self, mock_json):
  52 + mock_json.side_effect = [data.merge_json, []]
  53 +
  54 + merges = self.api.fetch_merge_request([GitlabProject()])
  55 + self.assertEqual(len(merges), 1)
  56 + self.assertEqual(merges[0].title, "Merge Title")
  57 + self.assertEqual(merges[0].description, "description")
  58 + self.assertEqual(merges[0].get_author().username, "user")
  59 +
  60 + @patch.object(GitlabDataImporter, 'get_json_data')
  61 + def test_fetch_issues(self, mock_json):
  62 + mock_json.side_effect = [data.issues_json, []]
  63 +
  64 + issues = self.api.fetch_issue([GitlabProject()])
  65 + assert mock_json.called
  66 + self.assertEqual(len(issues), 1)
  67 + self.assertEqual(issues[0].title, "title")
  68 + self.assertEqual(issues[0].description, "description")
  69 + self.assertEqual(issues[0].state, "opened")
  70 +
  71 + @patch.object(GitlabDataImporter, 'get_json_data')
  72 + def test_fetch_comments_mr(self, mock_json):
  73 + mock_json.side_effect = [data.comment_mr_json, []]
  74 +
  75 + comments_mr = self.api.fetch_comments_mr()
  76 + self.assertEqual(len(comments_mr), 1)
  77 + self.assertEqual(comments_mr[0].body, "message body")
  78 + self.assertEqual(comments_mr[0].user.username, "user")
  79 +
  80 + @patch.object(GitlabDataImporter, 'get_json_data')
  81 + def test_fetch_comments_issues(self, mock_json):
  82 + mock_json.side_effect = [data.comment_issue_json, []]
  83 +
  84 + comments_issue = self.api.fetch_comments_issues()
  85 + self.assertEqual(len(comments_issue), 1)
  86 + self.assertEqual(comments_issue[0].body, "message body")
  87 + self.assertEqual(comments_issue[0].user.username, "user")
  88 +
  89 + def test_fill_object_data(self):
  90 + issue = GitlabIssue()
  91 +
  92 + self.api.fill_object_data(data.issues_json[0], issue)
  93 + self.assertIsNotNone(issue.user)
  94 + self.assertEqual(issue.user.username, "user")
  95 + self.assertEqual(issue.created_at, parse("2014-10-11T16:25:37.548Z"))
  96 + self.assertEqual(issue.project_id, 32)
  97 + self.assertEqual(issue.title, "title")
colab/plugins/gitlab/tests/test_gitlab.py
@@ -3,20 +3,18 @@ Test User class. @@ -3,20 +3,18 @@ Test User class.
3 Objective: Test parameters, and behavior. 3 Objective: Test parameters, and behavior.
4 """ 4 """
5 from datetime import datetime 5 from datetime import datetime
6 -  
7 -  
8 from django.test import TestCase, Client 6 from django.test import TestCase, Client
9 -from colab.accounts.models import User  
10 -from colab.plugins.gitlab.models import GitlabProject, \  
11 - GitlabIssue, GitlabComment, GitlabMergeRequest 7 +from colab.plugins.gitlab.models import (GitlabProject, GitlabGroup,
  8 + GitlabIssue, GitlabComment,
  9 + GitlabMergeRequest)
12 10
13 11
14 class GitlabTest(TestCase): 12 class GitlabTest(TestCase):
15 13
  14 + fixtures = ['test_gitlab_data']
  15 +
16 def setUp(self): 16 def setUp(self):
17 - self.user = self.create_user()  
18 self.client = Client() 17 self.client = Client()
19 - self.create_gitlab_data()  
20 18
21 super(GitlabTest, self).setUp() 19 super(GitlabTest, self).setUp()
22 20
@@ -24,6 +22,7 @@ class GitlabTest(TestCase): @@ -24,6 +22,7 @@ class GitlabTest(TestCase):
24 pass 22 pass
25 23
26 def test_data_integrity(self): 24 def test_data_integrity(self):
  25 + self.assertEqual(GitlabGroup.objects.all().count(), 1)
27 self.assertEqual(GitlabProject.objects.all().count(), 2) 26 self.assertEqual(GitlabProject.objects.all().count(), 2)
28 self.assertEqual(GitlabMergeRequest.objects.all().count(), 2) 27 self.assertEqual(GitlabMergeRequest.objects.all().count(), 2)
29 self.assertEqual(GitlabIssue.objects.all().count(), 2) 28 self.assertEqual(GitlabIssue.objects.all().count(), 2)
@@ -33,6 +32,17 @@ class GitlabTest(TestCase): @@ -33,6 +32,17 @@ class GitlabTest(TestCase):
33 self.assertEqual(GitlabProject.objects.get(id=1).url, 32 self.assertEqual(GitlabProject.objects.get(id=1).url,
34 '/gitlab/softwarepublico/colab') 33 '/gitlab/softwarepublico/colab')
35 34
  35 + def test_project_group(self):
  36 + project = GitlabProject.objects.get(id=1)
  37 + self.assertEqual(project.name, 'colab')
  38 + self.assertEqual(project.namespace, 'softwarepublico')
  39 +
  40 + def test_namespace_projects(self):
  41 + group = GitlabGroup.objects.get(id=1)
  42 + self.assertEqual(len(group.projects), 2)
  43 + self.assertEqual(group.projects[0].name, 'colab')
  44 + self.assertEqual(group.projects[1].name, 'colabinc')
  45 +
36 def test_merge_request_url(self): 46 def test_merge_request_url(self):
37 self.assertEqual(GitlabMergeRequest.objects.get(id=1).url, 47 self.assertEqual(GitlabMergeRequest.objects.get(id=1).url,
38 '/gitlab/softwarepublico/colab/merge_requests/1') 48 '/gitlab/softwarepublico/colab/merge_requests/1')
@@ -52,100 +62,3 @@ class GitlabTest(TestCase): @@ -52,100 +62,3 @@ class GitlabTest(TestCase):
52 def test_comment_on_issue_url(self): 62 def test_comment_on_issue_url(self):
53 self.assertEqual(GitlabComment.objects.get(id=2).url, 63 self.assertEqual(GitlabComment.objects.get(id=2).url,
54 '/gitlab/softwarepublico/colab/issues/1#notes_2') 64 '/gitlab/softwarepublico/colab/issues/1#notes_2')
55 -  
56 - def create_gitlab_data(self):  
57 - g1 = GitlabProject()  
58 - g1.id = 1  
59 - g1.name = "colab"  
60 - g1.name_with_namespace = "Software Public / Colab"  
61 - g1.path_with_namespace = "softwarepublico/colab"  
62 - g1.created_at = datetime.now()  
63 - g1.last_activity_at = datetime.now()  
64 - g1.save()  
65 -  
66 - g2 = GitlabProject()  
67 - g2.id = 2  
68 - g2.name = "colabinc"  
69 - g2.name_with_namespace = "Software Public / ColabInc"  
70 - g2.path_with_namespace = "softwarepublico/colabinc"  
71 - g2.created_at = datetime.now()  
72 - g2.last_activity_at = datetime.now()  
73 - g2.save()  
74 -  
75 - mr1 = GitlabMergeRequest()  
76 - mr1.id = 1  
77 - mr1.iid = 1  
78 - mr1.project = g1  
79 - mr1.title = "Include plugin support"  
80 - mr1.description = "Merge request for plugin support"  
81 - mr1.state = "Closed"  
82 - mr1.created_at = datetime.now()  
83 - mr1.update_user(self.user.username)  
84 - mr1.save()  
85 -  
86 - mr2 = GitlabMergeRequest()  
87 - mr2.id = 2  
88 - mr2.iid = 1  
89 - mr2.project = g2  
90 - mr2.title = "Include test support"  
91 - mr2.description = "Merge request for test support"  
92 - mr2.state = "Closed"  
93 - mr2.created_at = datetime.now()  
94 - mr2.update_user(self.user.username)  
95 - mr2.save()  
96 -  
97 - i1 = GitlabIssue()  
98 - i1.id = 1  
99 - i1.iid = 1  
100 - i1.project = g1  
101 - i1.title = "Issue for colab"  
102 - i1.description = "Issue reported to colab"  
103 - i1.created_at = datetime.now()  
104 - i1.state = "Open"  
105 - i1.update_user(self.user.username)  
106 - i1.save()  
107 -  
108 - i2 = GitlabIssue()  
109 - i2.id = 2  
110 - i2.iid = 1  
111 - i2.project = g2  
112 - i2.title = "Issue for colab"  
113 - i2.description = "Issue reported to colab"  
114 - i2.created_at = datetime.now()  
115 - i2.state = "Open"  
116 - i2.update_user(self.user.username)  
117 - i2.save()  
118 -  
119 - c1 = GitlabComment()  
120 - c1.id = 1  
121 - c1.parent_id = mr1.iid  
122 - c1.project = g1  
123 - c1.body = "Comment to merge request"  
124 - c1.created_at = datetime.now()  
125 - c1.issue_comment = False  
126 - c1.update_user(self.user.username)  
127 - c1.save()  
128 -  
129 - c2 = GitlabComment()  
130 - c2.id = 2  
131 - c2.parent_id = i1.id  
132 - c2.project = g1  
133 - c2.body = "Comment to issue"  
134 - c2.created_at = datetime.now()  
135 - c2.issue_comment = True  
136 - c2.update_user(self.user.username)  
137 - c2.save()  
138 -  
139 - def create_user(self):  
140 - user = User()  
141 - user.username = "USERtestCoLaB"  
142 - user.set_password("123colab4")  
143 - user.email = "usertest@colab.com.br"  
144 - user.id = 1  
145 - user.twitter = "usertestcolab"  
146 - user.facebook = "usertestcolab"  
147 - user.first_name = "USERtestCoLaB"  
148 - user.last_name = "COLAB"  
149 - user.save()  
150 -  
151 - return user