#!/usr/bin/env python3
#
# Copyright 2021 Graviti. Licensed under MIT License.
#
"""Structures of dataset-scopic actions on the TensorBay."""
from functools import partial
from typing import Any, Dict, Optional, Tuple, Type, TypeVar
from tensorbay.utility import AttrsMixin, NameMixin, ReprMixin, attr, camel, common_loads
ROOT_COMMIT_ID = "00000000000000000000000000000000"
[docs]class TeamInfo(NameMixin):
"""This class defines the basic concept of a TensorBay team.
Arguments:
name: The name of the team.
email: The email of the team.
description: The description of the team.
"""
_T = TypeVar("_T", bound="TeamInfo")
_repr_attrs = ("email",)
email: Optional[str] = attr(default=None)
def __init__(self, name: str, *, email: Optional[str] = None, description: str = "") -> None:
super().__init__(name, description)
self.email = email
[docs] @classmethod
def loads(cls: Type[_T], contents: Dict[str, Any]) -> _T:
"""Loads a :class:`TeamInfo` instance from the given contents.
Arguments:
contents: A dict containing all the information of the commit::
{
"name": <str>
"email": <str>
"description": <str>
}
Returns:
A :class:`TeamInfo` instance containing all the information in the given contents.
"""
return common_loads(cls, contents)
[docs] def dumps(self) -> Dict[str, Any]:
"""Dumps all the information into a dict.
Returns:
A dict containing all the information of the team::
{
"name": <str>
"email": <str>
"description": <str>
}
"""
return self._dumps()
[docs]class UserInfo(NameMixin):
"""This class defines the basic concept of a TensorBay user.
Arguments:
name: The nickname of the user.
email: The email of the user.
mobile: The mobile of the user.
description: The description of the user.
team: The team of the user.
"""
_T = TypeVar("_T", bound="UserInfo")
_repr_attrs = ("email", "mobile", "team")
_name: str = attr(key="nickname")
email: Optional[str] = attr(default=None)
mobile: Optional[str] = attr(default=None)
team: Optional[TeamInfo] = attr(default=None)
def __init__(
self,
name: str,
*,
email: Optional[str] = None,
mobile: Optional[str] = None,
description: str = "",
team: Optional[TeamInfo] = None,
) -> None:
super().__init__(name, description=description)
self.email = email
self.mobile = mobile
self.team = team
[docs] @classmethod
def loads(cls: Type[_T], contents: Dict[str, Any]) -> _T:
"""Loads a :class:`UserInfo` instance from the given contents.
Arguments:
contents: A dict containing all the information of the commit::
{
"name": <str>
"email": <str>
"mobile": <str>
"description": <str>
"team": { <dict>
"name": <str>
"email": <str>
"description": <str>
}
}
Returns:
A :class:`UserInfo` instance containing all the information in the given contents.
"""
return common_loads(cls, contents)
[docs] def dumps(self) -> Dict[str, Any]:
"""Dumps all the information into a dict.
Returns:
A dict containing all the information of the user::
{
"name": <str>
"email": <str>
"mobile": <str>
"description": <str>
"team": { <dict>
"name": <str>
"email": <str>
"description": <str>
}
}
"""
return self._dumps()
[docs]class User(AttrsMixin, ReprMixin):
"""This class defines the basic concept of a user with an action.
Arguments:
name: The name of the user.
date: The date of the user action.
"""
_T = TypeVar("_T", bound="User")
_repr_attrs = ("date",)
name: str = attr()
date: int = attr()
def __init__(self, name: str, date: int) -> None:
self.name = name
self.date = date
def _repr_head(self) -> str:
return f'{self.__class__.__name__}("{self.name}")'
[docs] @classmethod
def loads(cls: Type[_T], contents: Dict[str, Any]) -> _T:
"""Loads a :class:`User` instance from the given contents.
Arguments:
contents: A dict containing all the information of the commit::
{
"name": <str>
"date": <int>
}
Returns:
A :class:`User` instance containing all the information in the given contents.
"""
return common_loads(cls, contents)
[docs] def dumps(self) -> Dict[str, Any]:
"""Dumps all the user information into a dict.
Returns:
A dict containing all the information of the user::
{
"name": <str>
"date": <int>
}
"""
return self._dumps()
[docs]class Commit(AttrsMixin, ReprMixin):
"""This class defines the structure of a commit.
Arguments:
commit_id: The commit id.
parent_commit_id: The parent commit id.
title: The commit title.
description: The commit description.
committer: The commit user.
"""
_T = TypeVar("_T", bound="Commit")
_repr_attrs: Tuple[str, ...] = ("parent_commit_id", "title", "committer")
_repr_maxlevel = 2
commit_id: str = attr(key=camel)
parent_commit_id: Optional[str] = attr(key=camel)
title: str = attr()
description: str = attr(default="")
committer: User = attr()
def __init__( # pylint: disable=too-many-arguments
self,
commit_id: str,
parent_commit_id: Optional[str],
title: str,
description: str,
committer: User,
) -> None:
self.commit_id = commit_id
self.parent_commit_id = parent_commit_id
self.title = title
self.description = description
self.committer = committer
def _repr_head(self) -> str:
return f'{self.__class__.__name__}("{self.commit_id}")'
[docs] @classmethod
def loads(cls: Type[_T], contents: Dict[str, Any]) -> _T:
"""Loads a :class:`Commit` instance for the given contents.
Arguments:
contents: A dict containing all the information of the commit::
{
"commitId": <str>
"parentCommitId": <str> or None
"title": <str>
"description": <str>
"committer": {
"name": <str>
"date": <int>
}
}
Returns:
A :class:`Commit` instance containing all the information in the given contents.
"""
return common_loads(cls, contents)
[docs] def dumps(self) -> Dict[str, Any]:
"""Dumps all the commit information into a dict.
Returns:
A dict containing all the information of the commit::
{
"commitId": <str>
"parentCommitId": <str> or None
"title": <str>
"description": <str>
"committer": {
"name": <str>
"date": <int>
}
}
"""
return self._dumps()
class _NamedCommit(Commit):
"""This class defines the structure of a named commit.
:class:`_NamedCommit` is the base class of :class:`Tag` and :class:`Branch`.
Arguments:
name: The name of the named commit.
commit_id: The commit id.
parent_commit_id: The parent commit id.
title: The commit title.
description: The commit description.
committer: The commit user.
"""
_T = TypeVar("_T", bound="_NamedCommit")
_repr_attrs = ("commit_id",) + Commit._repr_attrs
name: str = attr()
def __init__( # pylint: disable=too-many-arguments
self,
name: str,
commit_id: str,
parent_commit_id: Optional[str],
title: str,
description: str,
committer: User,
) -> None:
super().__init__(commit_id, parent_commit_id, title, description, committer)
self.name = name
def _repr_head(self) -> str:
return f'{self.__class__.__name__}("{self.name}")'
@classmethod
def loads(cls: Type[_T], contents: Dict[str, Any]) -> _T:
"""Loads a :class:`_NamedCommit` instance for the given contents.
Arguments:
contents: A dict containing all the information of the named commit::
{
"name": <str>
"commitId": <str>
"parentCommitId": <str> or None
"title": <str>
"description": <str>
"committer": {
"name": <str>
"date": <int>
}
}
Returns:
A :class:`_NamedCommit` instance containing all the information in the given contents.
"""
return common_loads(cls, contents)
def dumps(self) -> Dict[str, Any]:
"""Dumps all the named commit information into a dict.
Returns:
A dict containing all the information of the named commit::
{
"name": <str>
"commitId": <str>
"parentCommitId": <str> or None
"title": <str>
"description": <str>
"committer": {
"name": <str>
"date": <int>
}
}
"""
return self._dumps()
[docs]class Tag(_NamedCommit):
"""This class defines the structure of the tag of a commit.
Arguments:
name: The name of the tag.
commit_id: The commit id.
parent_commit_id: The parent commit id.
title: The commit title.
description: The commit description.
committer: The commit user.
"""
_ERROR_MESSAGE = "The '{attr_name}' is not available due to this branch has no commit history."
_attr = partial(attr, is_dynamic=True, error_message=_ERROR_MESSAGE)
[docs]class Branch(_NamedCommit):
"""This class defines the structure of a branch.
Arguments:
name: The name of the branch.
commit_id: The commit id.
parent_commit_id: The parent commit id.
title: The commit title.
description: The commit description.
committer: The commit user.
"""
parent_commit_id: Optional[str] = _attr(key=camel)
title: str = _attr()
description: str = _attr()
committer: User = _attr()
def _loads(self, contents: Dict[str, Any]) -> None:
self.name = contents["name"]
self.commit_id = contents["commitId"]
if self.commit_id == ROOT_COMMIT_ID:
return
self.parent_commit_id = contents["parentCommitId"]
self.title = contents["title"]
self.description = contents["description"]
self.committer = User.loads(contents["committer"])
[docs]class Draft(AttrsMixin, ReprMixin): # pylint: disable=too-many-instance-attributes
"""This class defines the basic structure of a draft.
Arguments:
number: The number of the draft.
title: The title of the draft.
branch_name: The branch name.
status: The status of the draft.
parent_commit_id: The parent commit id.
author: The author of the draft.
updated_at: The time of last update.
description: The draft description.
"""
_T = TypeVar("_T", bound="Draft")
_repr_attrs = ("title", "status", "branch_name")
number: int = attr()
title: str = attr()
branch_name: str = attr(key=camel)
status: str = attr()
parent_commit_id: str = attr(key=camel)
author: User = attr()
updated_at: int = attr(key=camel)
description: str = attr(default="")
def __init__( # pylint: disable=too-many-arguments
self,
number: int,
title: str,
branch_name: str,
status: str,
parent_commit_id: str,
author: User,
updated_at: int,
description: str = "",
) -> None:
self.number = number
self.title = title
self.branch_name = branch_name
self.status = status
self.parent_commit_id = parent_commit_id
self.author = author
self.updated_at = updated_at
self.description = description
def _repr_head(self) -> str:
return f"{self.__class__.__name__}({self.number})"
[docs] @classmethod
def loads(cls: Type[_T], contents: Dict[str, Any]) -> _T:
"""Loads a :class:`Draft` instance from the given contents.
Arguments:
contents: A dict containing all the information of the draft::
{
"number": <int>
"title": <str>
"branchName": <str>
"status": "OPEN", "CLOSED" or "COMMITTED"
"parentCommitId": <str>
"author": {
"name": <str>
"date": <int>
}
"updatedAt": <int>
"description": <str>
}
Returns:
A :class:`Draft` instance containing all the information in the given contents.
"""
return common_loads(cls, contents)
[docs] def dumps(self) -> Dict[str, Any]:
"""Dumps all the information of the draft into a dict.
Returns:
A dict containing all the information of the draft::
{
"number": <int>
"title": <str>
"branchName": <str>
"status": "OPEN", "CLOSED" or "COMMITTED"
"parentCommitId": <str>
"author": {
"name": <str>
"date": <int>
}
"updatedAt": <int>
"description": <str>
}
"""
return self._dumps()