Commit 5fe84f6f5ddff12b0d7e52d40adee82e822b94bc

Authored by Gust
1 parent 8b5c4784

Add gitlab code at colab_gitlab

Signed-off-by: Gustavo Jaruga <darksshades@gmail.com>
Signed-off-by: Alexandre Barbosa <alexandreab@live.com>
colab_gitlab/__init__.py 0 → 100644
... ... @@ -0,0 +1,3 @@
  1 +__version__ = '0.1.2'
  2 +
  3 +default_app_config = 'colab_gitlab.apps.ProxyGitlabAppConfig'
... ...
colab_gitlab/apps.py 0 → 100644
... ... @@ -0,0 +1,25 @@
  1 +
  2 +from django.utils.translation import ugettext_lazy as _
  3 +
  4 +from colab.plugins.utils.apps import ColabProxiedAppConfig
  5 +
  6 +
  7 +class ProxyGitlabAppConfig(ColabProxiedAppConfig):
  8 + name = 'colab_gitlab'
  9 + verbose_name = 'Gitlab Proxy'
  10 +
  11 + menu = {
  12 + 'title': _('Code'),
  13 + 'links': (
  14 + (_('Public Projects'), 'public/projects'),
  15 + ),
  16 + 'auth_links': (
  17 + (_('Profile'), 'profile'),
  18 + (_('New Project'), 'projects/new'),
  19 + (_('Projects'), 'dashboard/projects'),
  20 + (_('Groups'), 'profile/groups'),
  21 + (_('Issues'), 'dashboard/issues'),
  22 + (_('Merge Requests'), 'dashboard/merge_requests'),
  23 +
  24 + ),
  25 + }
... ...
colab_gitlab/data_api.py 0 → 100644
... ... @@ -0,0 +1,205 @@
  1 +import json
  2 +import urllib
  3 +import urllib2
  4 +import logging
  5 +
  6 +from dateutil.parser import parse
  7 +
  8 +from django.conf import settings
  9 +from django.db.models.fields import DateTimeField
  10 +
  11 +from colab_gitlab.models import (GitlabProject, GitlabMergeRequest,
  12 + GitlabComment, GitlabIssue)
  13 +from colab.plugins.utils.proxy_data_api import ProxyDataAPI
  14 +
  15 +LOGGER = logging.getLogger('colab.plugin.gitlab')
  16 +
  17 +
  18 +class GitlabDataAPI(ProxyDataAPI):
  19 +
  20 + def get_request_url(self, path, **kwargs):
  21 + proxy_config = settings.PROXIED_APPS.get(self.app_label, {})
  22 +
  23 + upstream = proxy_config.get('upstream')
  24 + kwargs['private_token'] = proxy_config.get('private_token')
  25 + params = urllib.urlencode(kwargs)
  26 +
  27 + if upstream[-1] == '/':
  28 + upstream = upstream[:-1]
  29 +
  30 + return u'{}{}?{}'.format(upstream, path, params)
  31 +
  32 + def get_json_data(self, api_url, page, pages=1000):
  33 + url = self.get_request_url(api_url, per_page=pages,
  34 + page=page)
  35 +
  36 + try:
  37 + data = urllib2.urlopen(url, timeout=10)
  38 + json_data = json.load(data)
  39 + except urllib2.URLError:
  40 + LOGGER.exception("Connection timeout: " + url)
  41 + json_data = []
  42 +
  43 + return json_data
  44 +
  45 + def fill_object_data(self, element, _object):
  46 + for field in _object._meta.fields:
  47 + try:
  48 + if field.name == "user":
  49 + _object.update_user(
  50 + element["author"]["username"])
  51 + continue
  52 + if field.name == "project":
  53 + _object.project_id = element["project_id"]
  54 + continue
  55 +
  56 + if isinstance(field, DateTimeField):
  57 + value = parse(element[field.name])
  58 + else:
  59 + value = element[field.name]
  60 +
  61 + setattr(_object, field.name, value)
  62 + except KeyError:
  63 + continue
  64 +
  65 + return _object
  66 +
  67 + def fetch_projects(self):
  68 + page = 1
  69 + projects = []
  70 +
  71 + while True:
  72 + json_data = self.get_json_data('/api/v3/projects/all', page)
  73 + page = page + 1
  74 +
  75 + if not len(json_data):
  76 + break
  77 +
  78 + for element in json_data:
  79 + project = GitlabProject()
  80 + self.fill_object_data(element, project)
  81 + projects.append(project)
  82 +
  83 + return projects
  84 +
  85 + def fetch_merge_request(self, projects):
  86 + all_merge_request = []
  87 +
  88 + for project in projects:
  89 + page = 1
  90 + while True:
  91 + url = '/api/v3/projects/{}/merge_requests'.format(project.id)
  92 + json_data_mr = self.get_json_data(url, page)
  93 + page = page + 1
  94 +
  95 + if len(json_data_mr) == 0:
  96 + break
  97 +
  98 + for element in json_data_mr:
  99 + single_merge_request = GitlabMergeRequest()
  100 + self.fill_object_data(element, single_merge_request)
  101 + all_merge_request.append(single_merge_request)
  102 +
  103 + return all_merge_request
  104 +
  105 + def fetch_issue(self, projects):
  106 + all_issues = []
  107 +
  108 + for project in projects:
  109 + page = 1
  110 + while True:
  111 + url = '/api/v3/projects/{}/issues'.format(project.id)
  112 + json_data_issue = self.get_json_data(url, page)
  113 + page = page + 1
  114 +
  115 + if len(json_data_issue) == 0:
  116 + break
  117 +
  118 + for element in json_data_issue:
  119 + single_issue = GitlabIssue()
  120 + self.fill_object_data(element, single_issue)
  121 + all_issues.append(single_issue)
  122 +
  123 + return all_issues
  124 +
  125 + def fetch_comments(self):
  126 + all_comments = []
  127 + all_comments.extend(self.fetch_comments_MR())
  128 + all_comments.extend(self.fetch_comments_issues())
  129 +
  130 + return all_comments
  131 +
  132 + def fetch_comments_MR(self):
  133 + all_comments = []
  134 + all_merge_requests = GitlabMergeRequest.objects.all()
  135 +
  136 + for merge_request in all_merge_requests:
  137 + page = 1
  138 + while True:
  139 + url = '/api/v3/projects/{}/merge_requests/{}/notes'.format(
  140 + merge_request.project_id, merge_request.id)
  141 + json_data_mr = self.get_json_data(url, page)
  142 + page = page + 1
  143 +
  144 + if len(json_data_mr) == 0:
  145 + break
  146 +
  147 + for element in json_data_mr:
  148 + single_comment = GitlabComment()
  149 + self.fill_object_data(element, single_comment)
  150 + single_comment.project = merge_request.project
  151 + single_comment.issue_comment = False
  152 + single_comment.parent_id = merge_request.id
  153 + all_comments.append(single_comment)
  154 +
  155 + return all_comments
  156 +
  157 + def fetch_comments_issues(self):
  158 + all_comments = []
  159 + all_issues = GitlabIssue.objects.all()
  160 +
  161 + for issue in all_issues:
  162 + page = 1
  163 + while True:
  164 + url = '/api/v3/projects/{}/issues/{}/notes'.format(
  165 + issue.project_id, issue.id)
  166 + json_data_mr = self.get_json_data(url, page)
  167 + page = page + 1
  168 +
  169 + if len(json_data_mr) == 0:
  170 + break
  171 +
  172 + for element in json_data_mr:
  173 + single_comment = GitlabComment()
  174 + self.fill_object_data(element, single_comment)
  175 + single_comment.project = issue.project
  176 + single_comment.issue_comment = True
  177 + single_comment.parent_id = issue.id
  178 + all_comments.append(single_comment)
  179 +
  180 + return all_comments
  181 +
  182 + def fetch_data(self):
  183 + LOGGER.info("Importing Projects")
  184 + projects = self.fetch_projects()
  185 + for datum in projects:
  186 + datum.save()
  187 +
  188 + LOGGER.info("Importing Merge Requests")
  189 + merge_request_list = self.fetch_merge_request(projects)
  190 + for datum in merge_request_list:
  191 + datum.save()
  192 +
  193 + LOGGER.info("Importing Issues")
  194 + issue_list = self.fetch_issue(projects)
  195 + for datum in issue_list:
  196 + datum.save()
  197 +
  198 + LOGGER.info("Importing Comments")
  199 + comments_list = self.fetch_comments()
  200 + for datum in comments_list:
  201 + datum.save()
  202 +
  203 + @property
  204 + def app_label(self):
  205 + return 'gitlab'
... ...
colab_gitlab/diazo.xml 0 → 100644
... ... @@ -0,0 +1,18 @@
  1 +<rules
  2 + xmlns="http://namespaces.plone.org/diazo"
  3 + xmlns:css="http://namespaces.plone.org/diazo/css"
  4 + xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  5 +
  6 + <before theme-children="/html/head" content-children="/html/head" />
  7 + <before css:theme-children="#main-content" css:content-children="body" />
  8 +
  9 + <merge attributes="class" css:theme="body" css:content="body" />
  10 +
  11 + <!-- Add gitlab properties -->
  12 + <merge attributes="data-page" css:theme="body" css:content="body" />
  13 + <merge attributes="data-project-id" css:theme="body" css:content="body" />
  14 +
  15 + <drop css:content="#top-panel" />
  16 + <drop css:content=".navbar-gitlab" />
  17 + <drop css:content=".git-clone-holder .btn:contains('HTTPS')" />
  18 +</rules>
... ...
colab_gitlab/migrations/0001_initial.py 0 → 100644
... ... @@ -0,0 +1,28 @@
  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 + ]
  11 +
  12 + operations = [
  13 + migrations.CreateModel(
  14 + name='GitlabProject',
  15 + fields=[
  16 + ('id', models.IntegerField(serialize=False, primary_key=True)),
  17 + ('description', models.TextField()),
  18 + ('public', models.BooleanField(default=True)),
  19 + ('name', models.TextField()),
  20 + ('name_with_namespace', models.TextField()),
  21 + ('created_at', models.DateTimeField(blank=True)),
  22 + ('last_activity_at', models.DateTimeField(blank=True)),
  23 + ],
  24 + options={
  25 + },
  26 + bases=(models.Model,),
  27 + ),
  28 + ]
... ...
colab_gitlab/migrations/0002_auto_20150205_1220.py 0 → 100644
... ... @@ -0,0 +1,69 @@
  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 + ('colab_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='colab_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='colab_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_gitlab/migrations/0003_auto_20150211_1203.py 0 → 100644
... ... @@ -0,0 +1,61 @@
  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 + ('colab_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='colab_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_gitlab/migrations/__init__.py 0 → 100644
colab_gitlab/models.py 0 → 100644
... ... @@ -0,0 +1,143 @@
  1 +from django.db import models
  2 +from django.utils.translation import ugettext_lazy as _
  3 +from colab.plugins.utils.models import Collaboration
  4 +from hitcounter.models import HitCounterModelMixin
  5 +
  6 +
  7 +class GitlabProject(models.Model, HitCounterModelMixin):
  8 +
  9 + id = models.IntegerField(primary_key=True)
  10 + description = models.TextField()
  11 + public = models.BooleanField(default=True)
  12 + name = models.TextField()
  13 + name_with_namespace = models.TextField()
  14 + created_at = models.DateTimeField(blank=True)
  15 + last_activity_at = models.DateTimeField(blank=True)
  16 + path_with_namespace = models.TextField(blank=True, null=True)
  17 +
  18 + @property
  19 + def url(self):
  20 + return u'/gitlab/{}'.format(self.path_with_namespace)
  21 +
  22 + class Meta:
  23 + verbose_name = _('Gitlab Project')
  24 + verbose_name_plural = _('Gitlab Projects')
  25 +
  26 +
  27 +class GitlabMergeRequest(Collaboration):
  28 +
  29 + id = models.IntegerField(primary_key=True)
  30 + target_branch = models.TextField()
  31 + source_branch = models.TextField()
  32 + project = models.ForeignKey(GitlabProject, null=True,
  33 + on_delete=models.SET_NULL)
  34 + description = models.TextField()
  35 + title = models.TextField()
  36 + state = models.TextField()
  37 + created_at = models.DateTimeField(blank=True, null=True)
  38 +
  39 + @property
  40 + def modified(self):
  41 + return self.created_at
  42 +
  43 + @property
  44 + def tag(self):
  45 + return self.state
  46 +
  47 + type = u'merge_request'
  48 + icon_name = u'file'
  49 +
  50 + @property
  51 + def url(self):
  52 + return u'/gitlab/{}/merge_requests/{}'.format(
  53 + self.project.path_with_namespace, self.id)
  54 +
  55 + def get_author(self):
  56 + return self.user
  57 +
  58 + class Meta:
  59 + verbose_name = _('Gitlab Merge Request')
  60 + verbose_name_plural = _('Gitlab Merge Requests')
  61 +
  62 +
  63 +class GitlabIssue(Collaboration):
  64 +
  65 + id = models.IntegerField(primary_key=True)
  66 + project = models.ForeignKey(GitlabProject, null=True,
  67 + on_delete=models.SET_NULL)
  68 + title = models.TextField()
  69 + description = models.TextField()
  70 +
  71 + state = models.TextField()
  72 + created_at = models.DateTimeField(blank=True, null=True)
  73 +
  74 + icon_name = u'align-right'
  75 + type = u'gitlab_issue'
  76 +
  77 + @property
  78 + def modified(self):
  79 + return self.created_at
  80 +
  81 + @property
  82 + def url(self):
  83 + return u'/gitlab/{}/issues/{}'.format(
  84 + self.project.path_with_namespace, self.id)
  85 +
  86 + class Meta:
  87 + verbose_name = _('Gitlab Issue')
  88 + verbose_name_plural = _('Gitlab Issues')
  89 +
  90 +
  91 +class GitlabComment(Collaboration):
  92 +
  93 + id = models.IntegerField(primary_key=True)
  94 + body = models.TextField()
  95 + created_at = models.DateTimeField(blank=True, null=True)
  96 + issue_comment = models.BooleanField(default=True)
  97 +
  98 + project = models.ForeignKey(GitlabProject, null=True,
  99 + on_delete=models.SET_NULL)
  100 +
  101 + parent_id = models.IntegerField(null=True)
  102 + type = u'comment'
  103 +
  104 + @property
  105 + def modified(self):
  106 + return self.created_at
  107 +
  108 + @property
  109 + def title(self):
  110 + if self.issue_comment:
  111 + issue = GitlabIssue.objects.get(id=self.parent_id)
  112 + return issue.title
  113 + else:
  114 + merge_request = GitlabMergeRequest.objects.get(id=self.parent_id)
  115 + return merge_request.title
  116 +
  117 + icon_name = u'align-right'
  118 +
  119 + @property
  120 + def description(self):
  121 + return self.body
  122 +
  123 + @property
  124 + def tag(self):
  125 + if self.issue_comment:
  126 + issue = GitlabIssue.objects.get(id=self.parent_id)
  127 + return issue.state
  128 + else:
  129 + merge_request = GitlabMergeRequest.objects.get(id=self.parent_id)
  130 + return merge_request.state
  131 +
  132 + @property
  133 + def url(self):
  134 + if self.issue_comment:
  135 + return u'/gitlab/{}/issues/{}#notes_{}'.format(
  136 + self.project.path_with_namespace, self.parent_id, self.id)
  137 + else:
  138 + return u'/gitlab/{}/merge_requests/{}#notes_{}'.format(
  139 + self.project.path_with_namespace, self.parent_id, self.id)
  140 +
  141 + class Meta:
  142 + verbose_name = _('Gitlab Comments')
  143 + verbose_name_plural = _('Gitlab Comments')
... ...
colab_gitlab/search_indexes.py 0 → 100644
... ... @@ -0,0 +1,120 @@
  1 +# -*- coding: utf-8 -*-
  2 +
  3 +import string
  4 +
  5 +from haystack import indexes
  6 +from haystack.utils import log as logging
  7 +
  8 +from .models import (GitlabProject, GitlabMergeRequest,
  9 + GitlabIssue, GitlabComment)
  10 +
  11 +
  12 +logger = logging.getLogger('haystack')
  13 +
  14 +# The string maketrans always return a string encoded with latin1
  15 +# http://stackoverflow.com/questions/1324067/how-do-i-get-str-translate-to-work-with-unicode-strings
  16 +table = string.maketrans(
  17 + string.punctuation,
  18 + '.' * len(string.punctuation)
  19 +).decode('latin1')
  20 +
  21 +
  22 +class GitlabProjectIndex(indexes.SearchIndex, indexes.Indexable):
  23 + text = indexes.CharField(document=True, use_template=False, stored=False)
  24 + title = indexes.CharField(model_attr='name')
  25 + description = indexes.CharField(model_attr='description', null=True)
  26 + tag = indexes.CharField()
  27 + url = indexes.CharField(model_attr='url', indexed=False)
  28 + icon_name = indexes.CharField()
  29 + type = indexes.CharField()
  30 + created = indexes.DateTimeField(model_attr='created_at', null=True)
  31 +
  32 + def prepare_tag(self, obj):
  33 + return "{}".format(obj.name_with_namespace.split('/')[0].strip())
  34 +
  35 + def prepare_icon_name(self, obj):
  36 + return u'file'
  37 +
  38 + def get_ful_name(self):
  39 + self.objs.name
  40 +
  41 + def get_model(self):
  42 + return GitlabProject
  43 +
  44 + def prepare_type(self, obj):
  45 + return u'gitlab'
  46 +
  47 +
  48 +class GitlabMergeRequestIndex(indexes.SearchIndex, indexes.Indexable):
  49 +
  50 + text = indexes.CharField(document=True, use_template=False, stored=False)
  51 + title = indexes.CharField(model_attr='title')
  52 + description = indexes.CharField(model_attr='description')
  53 + tag = indexes.CharField(model_attr='state')
  54 + url = indexes.CharField(model_attr='url', indexed=False)
  55 + icon_name = indexes.CharField()
  56 + type = indexes.CharField(model_attr='type')
  57 +
  58 + modified_by = indexes.CharField(model_attr='modified_by', null=True)
  59 + modified_by_url = indexes.CharField(model_attr='modified_by_url',
  60 + null=True)
  61 + modified = indexes.DateTimeField(model_attr='created_at', null=True)
  62 +
  63 + def get_model(self):
  64 + return GitlabMergeRequest
  65 +
  66 + def prepare_icon_name(self, obj):
  67 + return u'file'
  68 +
  69 + def prepare_type(self, obj):
  70 + return u'merge_request'
  71 +
  72 +
  73 +class GitlabIssueIndex(indexes.SearchIndex, indexes.Indexable):
  74 +
  75 + text = indexes.CharField(document=True, use_template=False, stored=False)
  76 + title = indexes.CharField(model_attr='title')
  77 + description = indexes.CharField(model_attr='description')
  78 + tag = indexes.CharField(model_attr='state')
  79 + url = indexes.CharField(model_attr='url', indexed=False)
  80 + icon_name = indexes.CharField()
  81 + type = indexes.CharField(model_attr='type')
  82 +
  83 + modified_by = indexes.CharField(model_attr='modified_by', null=True)
  84 + modified_by_url = indexes.CharField(model_attr='modified_by_url',
  85 + null=True)
  86 + modified = indexes.DateTimeField(model_attr='created_at', null=True)
  87 +
  88 + def get_model(self):
  89 + return GitlabIssue
  90 +
  91 + def prepare_icon_name(self, obj):
  92 + return u'align-right'
  93 +
  94 + def prepare_type(self, obj):
  95 + return u'merge_request'
  96 +
  97 +
  98 +class GitlabCommentIndex(indexes.SearchIndex, indexes.Indexable):
  99 +
  100 + text = indexes.CharField(document=True, use_template=False, stored=False)
  101 + title = indexes.CharField(model_attr='title')
  102 + description = indexes.CharField(model_attr='description')
  103 + tag = indexes.CharField()
  104 + url = indexes.CharField(model_attr='url', indexed=False)
  105 + icon_name = indexes.CharField()
  106 + type = indexes.CharField(model_attr='type')
  107 +
  108 + modified_by = indexes.CharField(model_attr='modified_by', null=True)
  109 + modified_by_url = indexes.CharField(model_attr='modified_by_url',
  110 + null=True)
  111 + modified = indexes.DateTimeField(model_attr='created_at', null=True)
  112 +
  113 + def get_model(self):
  114 + return GitlabComment
  115 +
  116 + def prepare_icon_name(self, obj):
  117 + return u'align-right'
  118 +
  119 + def prepare_tag(self, obj):
  120 + return obj.tag
... ...
colab_gitlab/templates/proxy/gitlab.html 0 → 100644
... ... @@ -0,0 +1,51 @@
  1 +{% extends 'base.html' %}
  2 +{% load static from staticfiles %}
  3 +
  4 +{% block head_css %}
  5 +<style>
  6 + /* Reset left and with for .modal-dialog style (like gitlab does),
  7 + the bootstrap.css one makes it small */
  8 + @media screen and (min-width: 768px) {
  9 + .modal-dialog {
  10 + left: auto;
  11 + width: auto;
  12 + }
  13 + }
  14 + div#main-content {
  15 + margin-top: 65px;
  16 + }
  17 +
  18 + div#main-content div.container {
  19 + width: 1110px;
  20 + }
  21 + div#main-content div.flash-container{
  22 + width: 85%;
  23 + }
  24 + #breadcrumbs {
  25 + border: 0 !important;
  26 + }
  27 +
  28 + #right-top-nav {
  29 + margin-right: 5em !important;
  30 + }
  31 +</style>
  32 +{% endblock %}
  33 +
  34 +{% block head_js %}
  35 +<script type="text/javascript">
  36 + jQuery(function(){
  37 + // bootstrap.css forces .hide {display:none!important}, and this makes
  38 + // gitlab .hide elements NEVER have a display:block, so
  39 + // instead of editing bootstrap.css, we just removed '.hide' css class and
  40 + // toggled
  41 + jQuery('.hide').removeClass('hide').css('display', 'none');
  42 +
  43 + // Hit the SSH clone button to select it by default
  44 + jQuery(".git-clone-holder .btn:contains('SSH')").click()
  45 +
  46 + });
  47 +</script>
  48 +<script type="text/javascript" src="{% static 'third-party/bootstrap/js/bootstrap.min.js' %}"></script>
  49 +<script type="text/javascript" src="{% static 'third-party/jquery.cookie.js' %}"></script>
  50 +<script>jQuery.noConflict();</script>
  51 +{% endblock %}
... ...
colab_gitlab/tests/__init__.py 0 → 100644
colab_gitlab/tests/test_gitlab.py 0 → 100644
... ... @@ -0,0 +1,114 @@
  1 +"""
  2 +Test User class.
  3 +Objective: Test parameters, and behavior.
  4 +"""
  5 +from datetime import datetime
  6 +
  7 +
  8 +from django.test import TestCase, Client
  9 +from colab.accounts.models import User
  10 +from colab_gitlab.models import GitlabProject, \
  11 + GitlabIssue, GitlabComment, GitlabMergeRequest
  12 +
  13 +
  14 +class GitlabTest(TestCase):
  15 +
  16 + def setUp(self):
  17 + self.user = self.create_user()
  18 + self.client = Client()
  19 + self.create_gitlab_data()
  20 +
  21 + super(GitlabTest, self).setUp()
  22 +
  23 + def tearDown(self):
  24 + pass
  25 +
  26 + def test_data_integrity(self):
  27 + self.assertEqual(GitlabProject.objects.all().count(), 1)
  28 + self.assertEqual(GitlabMergeRequest.objects.all().count(), 1)
  29 + self.assertEqual(GitlabIssue.objects.all().count(), 1)
  30 + self.assertEqual(GitlabComment.objects.all().count(), 2)
  31 +
  32 + def test_project_url(self):
  33 + self.assertEqual(GitlabProject.objects.get(id=1).url,
  34 + '/gitlab/softwarepublico/colab')
  35 +
  36 + def test_merge_request_url(self):
  37 + self.assertEqual(GitlabMergeRequest.objects.get(id=1).url,
  38 + '/gitlab/softwarepublico/colab/merge_requests/1')
  39 +
  40 + def test_issue_url(self):
  41 + self.assertEqual(GitlabIssue.objects.get(id=1).url,
  42 + '/gitlab/softwarepublico/colab/issues/1')
  43 +
  44 + def test_comment_on_mr_url(self):
  45 + url = '/gitlab/softwarepublico/colab/merge_requests/1#notes_1'
  46 + self.assertEqual(GitlabComment.objects.get(id=1).url, url)
  47 +
  48 + def test_comment_on_issue_url(self):
  49 + self.assertEqual(GitlabComment.objects.get(id=2).url,
  50 + '/gitlab/softwarepublico/colab/issues/1#notes_2')
  51 +
  52 + def create_gitlab_data(self):
  53 + g = GitlabProject()
  54 + g.id = 1
  55 + g.name = "colab"
  56 + g.name_with_namespace = "Software Public / Colab"
  57 + g.path_with_namespace = "softwarepublico/colab"
  58 + g.created_at = datetime.now()
  59 + g.last_activity_at = datetime.now()
  60 + g.save()
  61 +
  62 + mr = GitlabMergeRequest()
  63 + mr.id = 1
  64 + mr.project = g
  65 + mr.title = "Include plugin support"
  66 + mr.description = "Merge request for plugin support"
  67 + mr.state = "Closed"
  68 + mr.created_at = datetime.now()
  69 + mr.update_user(self.user.username)
  70 + mr.save()
  71 +
  72 + i = GitlabIssue()
  73 + i.id = 1
  74 + i.project = g
  75 + i.title = "Issue for colab"
  76 + i.description = "Issue reported to colab"
  77 + i.created_at = datetime.now()
  78 + i.state = "Open"
  79 + i.update_user(self.user.username)
  80 + i.save()
  81 +
  82 + c1 = GitlabComment()
  83 + c1.id = 1
  84 + c1.parent_id = mr.id
  85 + c1.project = g
  86 + c1.body = "Comment to merge request"
  87 + c1.created_at = datetime.now()
  88 + c1.issue_comment = False
  89 + c1.update_user(self.user.username)
  90 + c1.save()
  91 +
  92 + c2 = GitlabComment()
  93 + c2.id = 2
  94 + c2.parent_id = i.id
  95 + c2.project = g
  96 + c2.body = "Comment to issue"
  97 + c2.created_at = datetime.now()
  98 + c2.issue_comment = True
  99 + c2.update_user(self.user.username)
  100 + c2.save()
  101 +
  102 + def create_user(self):
  103 + user = User()
  104 + user.username = "USERtestCoLaB"
  105 + user.set_password("123colab4")
  106 + user.email = "usertest@colab.com.br"
  107 + user.id = 1
  108 + user.twitter = "usertestcolab"
  109 + user.facebook = "usertestcolab"
  110 + user.first_name = "USERtestCoLaB"
  111 + user.last_name = "COLAB"
  112 + user.save()
  113 +
  114 + return user
... ...
colab_gitlab/urls.py 0 → 100644
... ... @@ -0,0 +1,9 @@
  1 +
  2 +from django.conf.urls import patterns, url
  3 +
  4 +from .views import GitlabProxyView
  5 +
  6 +urlpatterns = patterns('',
  7 + # Gitlab URLs
  8 + url(r'^(?P<path>.*)$', GitlabProxyView.as_view(), name='gitlab'),
  9 +)
... ...
colab_gitlab/views.py 0 → 100644
... ... @@ -0,0 +1,7 @@
  1 +
  2 +from colab.plugins.utils.views import ColabProxyView
  3 +
  4 +
  5 +class GitlabProxyView(ColabProxyView):
  6 + app_label = 'gitlab'
  7 + diazo_theme_template = 'proxy/gitlab.html'
... ...