Verified Commit 86f030e0 authored by Huste, Tobias (FWCC) - 111645's avatar Huste, Tobias (FWCC) - 111645
Browse files

api: basic gitlab release API class

parent 8cd1adfa
Pipeline #8621 failed with stage
in 6 minutes and 48 seconds
......@@ -28,8 +28,9 @@ from invenio_oauth2server.models import Token as ProviderToken
from invenio_oauthclient.handlers import token_getter
from invenio_oauthclient.models import RemoteAccount, RemoteToken
from invenio_oauthclient.proxies import current_oauthclient
from six import string_types
from werkzeug.local import LocalProxy
from werkzeug.utils import cached_property
from werkzeug.utils import cached_property, import_string
from .models import Project
from .utils import iso_utcnow, parse_timestamp, utcnow
......@@ -230,3 +231,134 @@ class GitLabAPI(object):
)
return True
return False
class GitLabRelease(object):
"""A GitLab release."""
def __init__(self, release):
"""Init GitLab release."""
self.model = release
@cached_property
def gl(self):
"""Return GitLab API object."""
return GitLabAPI(user_id=self.event.user_id)
@cached_property
def deposit_class(self):
"""Return a class implementing the `publish` method."""
cls = current_app.config['GITLAB_DEPOSIT_CLASS']
if isinstance(cls, string_types):
cls = import_string(cls)
assert isinstance(cls, type)
return cls
@cached_property
def event(self):
"""Get the release event."""
return self.model.event
@cached_property
def payload(self):
"""Return release metadata."""
return self.event.payload
@cached_property
def tag(self):
"""Return tag metadata."""
project = self.gl.api.projects.get(self.payload['project_id'])
tag = project.tags.get(self.payload['ref'].split('refs/tags/')[1])
return tag.attributes
@cached_property
def commit_sha(self):
"""Return commit sha of the current release."""
return self.event.payload['checkout_sha']
@cached_property
def project(self):
"""Return project metadata."""
return self.event.payload['project']
@cached_property
def title(self):
"""Extract title from a release."""
if self.event:
if (self.project['name']
not in self.project['path_with_namespace']):
return u'{0}: {1}'.format(
self.project['path_with_namespace'], self.project['name']
)
return u'{0}: {1}'.format(self.project['path_with_namespace'],
self.tag['name'])
@cached_property
def description(self):
"""Return project description."""
return self.project['description']
@cached_property
def related_identifiers(self):
"""Yield releated identifiers."""
yield dict(
identifier=u'{0}/tree/{1}'.format(
self.project['web_url'], self.tag['name']
),
relation='isSupplementTo',
)
@cached_property
def defaults(self):
"""Return default metadata."""
return dict(
access_right='open',
title=self.title,
description=self.description,
license='other-open',
publication_date=self.tag['commit']['created_at'][:10],
related_identifiers=list(self.related_identifiers),
version=self.tag['name'],
upload_type='software',
)
@cached_property
def filename(self):
"""Extract files to download from the GitLab payload."""
tag_name = self.event.payload['ref'].split('refs/tags/')[1]
project_name = self.project['path_with_namespace']
filename = u'{name}-{tag}.tar.gz'.format(
name=project_name, tag=tag_name)
return filename
@property
def metadata(self):
"""Return extracted metadata."""
output = dict(self.defaults)
# TODO: update metadata with additional metadata here
return output
@cached_property
def status(self):
"""Return the release status of the model."""
return self.model.status
def publish(self):
"""Publish GitLab release as a record."""
with db.session.begin_nested():
deposit = self.deposit_class.create(self.metadata)
deposit['_deposit']['created_by'] = self.event.user_id
deposit['_deposit']['owners'] = [self.event.user_id]
# Fetch the deposit files
project = self.gl.api.projects.get(self.payload['project_id'])
deposit.files[self.filename] = project.repository_archive(
sha=self.commit_sha,
streamed=True,
)
deposit.publish()
recid, record = deposit.fetch_published()
self.model.recordmetadata = record.model
......@@ -59,6 +59,9 @@ This variable must be set explicitly. Example:
context, doesn't work as expected.
"""
GITLAB_DEPOSIT_CLASS = 'invenio_deposit.api:Deposit'
"""Deposit class that implements a `publish` method."""
GITLAB_WEBHOOK_RECEIVER_ID = 'gitlab'
"""Local name of webhook receiver."""
......
......@@ -76,6 +76,7 @@ install_requires = [
'invenio-oauth2server>=1.0.0',
'invenio-records>=1.0.0',
'invenio-webhooks>=1.0.0a4',
'oauthlib>=2.0.0,<3.0.0',
'python-gitlab>=1.7.0',
]
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment