# -*- coding: utf-8 -*-
"""
github3.git
===========
This module contains all the classes relating to Git Data.
See also: http://developer.github.com/v3/git/
"""
from __future__ import unicode_literals
from json import dumps
from base64 import b64decode
from .models import GitHubCore, BaseCommit
from .users import User
from .decorators import requires_auth
class Blob(GitHubCore):
"""The :class:`Blob ` object.
See also: http://developer.github.com/v3/git/blobs/
"""
def _update_attributes(self, blob):
self._api = blob.get('url', '')
#: Raw content of the blob.
self.content = blob.get('content').encode()
#: Encoding of the raw content.
self.encoding = blob.get('encoding')
#: Decoded content of the blob.
self.decoded = self.content
if self.encoding == 'base64':
self.decoded = b64decode(self.content)
#: Size of the blob in bytes
self.size = blob.get('size')
#: SHA1 of the blob
self.sha = blob.get('sha')
def _repr(self):
return ''.format(self.sha)
class GitData(GitHubCore):
"""The :class:`GitData ` object. This isn't directly returned to
the user (developer) ever. This is used to prevent duplication of some
common items among other Git Data objects.
"""
def _update_attributes(self, data):
#: SHA of the object
self.sha = data.get('sha')
self._api = data.get('url', '')
class Commit(BaseCommit):
"""The :class:`Commit ` object. This represents a commit made in a
repository.
See also: http://developer.github.com/v3/git/commits/
"""
def _update_attributes(self, commit):
super(Commit, self)._update_attributes(commit)
#: dict containing at least the name, email and date the commit was
#: created
self.author = commit.get('author', {}) or {}
# If GH returns nil/None then make sure author is a dict
self._author_name = self.author.get('name', '')
#: dict containing similar information to the author attribute
self.committer = commit.get('committer', {}) or {}
# blank the data if GH returns no data
self._commit_name = self.committer.get('name', '')
#: :class:`Tree ` the commit belongs to.
self.tree = None
if commit.get('tree'):
self.tree = Tree(commit.get('tree'), self)
def _repr(self):
return ''.format(self._author_name, self.sha)
def author_as_User(self):
"""Attempt to return the author attribute as a
:class:`User `. No guarantees are made about the
validity of this object, i.e., having a login or created_at object.
"""
return User(self.author, self)
def committer_as_User(self):
"""Attempt to return the committer attribute as a
:class:`User ` object. No guarantees are made
about the validity of this object.
"""
return User(self.committer, self)
class Reference(GitHubCore):
"""The :class:`Reference ` object. This represents a reference
created on a repository.
See also: http://developer.github.com/v3/git/refs/
"""
def _update_attributes(self, ref):
self._api = ref.get('url', '')
#: The reference path, e.g., refs/heads/sc/featureA
self.ref = ref.get('ref')
#: :class:`GitObject ` the reference points to
self.object = GitObject(ref.get('object', {}))
def _repr(self):
return ''.format(self.ref)
@requires_auth
def delete(self):
"""Delete this reference.
:returns: bool
"""
return self._boolean(self._delete(self._api), 204, 404)
@requires_auth
def update(self, sha, force=False):
"""Update this reference.
:param str sha: (required), sha of the reference
:param bool force: (optional), force the update or not
:returns: bool
"""
data = {'sha': sha, 'force': force}
json = self._json(self._patch(self._api, data=dumps(data)), 200)
if json:
self._update_attributes(json)
return True
return False
class GitObject(GitData):
"""The :class:`GitObject ` object."""
def _update_attributes(self, obj):
super(GitObject, self)._update_attributes(obj)
#: The type of object.
self.type = obj.get('type')
def _repr(self):
return ''.format(self.sha)
class Tag(GitData):
"""The :class:`Tag ` object.
See also: http://developer.github.com/v3/git/tags/
"""
def _update_attributes(self, tag):
super(Tag, self)._update_attributes(tag)
#: String of the tag
self.tag = tag.get('tag')
#: Commit message for the tag
self.message = tag.get('message')
#: dict containing the name and email of the person
self.tagger = tag.get('tagger')
#: :class:`GitObject ` for the tag
self.object = GitObject(tag.get('object', {}))
def _repr(self):
return ''.format(self.tag)
class Tree(GitData):
"""The :class:`Tree ` object.
See also: http://developer.github.com/v3/git/trees/
"""
def _update_attributes(self, tree):
super(Tree, self)._update_attributes(tree)
#: list of :class:`Hash ` objects
self.tree = [Hash(t) for t in tree.get('tree', [])]
def _repr(self):
return ''.format(self.sha)
def __eq__(self, other):
return self.as_dict() == other.as_dict()
def __ne__(self, other):
return self.as_dict() != other.as_dict()
def recurse(self):
"""Recurse into the tree.
:returns: :class:`Tree `
"""
json = self._json(self._get(self._api, params={'recursive': '1'}),
200)
return self._instance_or_null(Tree, json)
class Hash(GitHubCore):
"""The :class:`Hash ` object.
See also: http://developer.github.com/v3/git/trees/#create-a-tree
"""
def _update_attributes(self, info):
#: Path to file
self.path = info.get('path')
#: File mode
self.mode = info.get('mode')
#: Type of hash, e.g., blob
self.type = info.get('type')
#: Size of hash
self.size = info.get('size')
#: SHA of the hash
self.sha = info.get('sha')
#: URL of this object in the GitHub API
self.url = info.get('url')
def _repr(self):
return ''.format(self.sha)