Files
Yiqun/gitea-shim/python/models/user.py

246 lines
7.8 KiB
Python

"""User model that provides GitHub-compatible interface for Gitea users."""
from typing import Optional, List, Dict, Any
class User:
"""
User wrapper that provides GitHub-compatible interface for Gitea users.
"""
def __init__(self, gitea_user, gitea_client):
"""
Initialize user wrapper.
Args:
gitea_user: The Gitea user object
gitea_client: The Gitea client instance
"""
self._user = gitea_user
self._gitea = gitea_client
# Map Gitea attributes to GitHub attributes
self.login = gitea_user.login
self.id = gitea_user.id
self.avatar_url = gitea_user.avatar_url
self.html_url = gitea_user.html_url
self.type = 'User' # Could be 'User' or 'Organization'
self.name = gitea_user.full_name
self.company = getattr(gitea_user, 'company', None)
self.blog = getattr(gitea_user, 'website', None)
self.location = gitea_user.location
self.email = gitea_user.email
self.bio = getattr(gitea_user, 'description', None)
self.public_repos = getattr(gitea_user, 'public_repos', 0)
self.followers = getattr(gitea_user, 'followers_count', 0)
self.following = getattr(gitea_user, 'following_count', 0)
self.created_at = gitea_user.created
self.updated_at = getattr(gitea_user, 'last_login', gitea_user.created)
def get_repos(self, type: str = 'owner', sort: str = 'full_name',
direction: str = 'asc') -> List[Any]:
"""
Get repositories for the user.
Args:
type: Type of repos to return ('all', 'owner', 'member')
sort: Sort field ('created', 'updated', 'pushed', 'full_name')
direction: Sort direction ('asc', 'desc')
Returns:
List of Repository objects
"""
# Import here to avoid circular imports
try:
# When running tests or using as a module
from models.repository import Repository
except ImportError:
# When using as a package
from .repository import Repository
# Get repos using Gitea API
gitea_repos = self._user.get_repos()
# Convert to Repository objects
repos = [Repository(repo, self._gitea) for repo in gitea_repos]
# Apply sorting
if sort == 'full_name':
repos.sort(key=lambda r: r.full_name, reverse=(direction == 'desc'))
elif sort == 'created':
repos.sort(key=lambda r: r.created_at, reverse=(direction == 'desc'))
elif sort == 'updated':
repos.sort(key=lambda r: r.updated_at, reverse=(direction == 'desc'))
return repos
def get_starred(self) -> List[Any]:
"""
Get repositories starred by the user.
Returns:
List of Repository objects
"""
# Import here to avoid circular imports
try:
# When running tests or using as a module
from models.repository import Repository
except ImportError:
# When using as a package
from .repository import Repository
# Get starred repos using Gitea API
gitea_repos = self._user.get_starred()
# Convert to Repository objects
return [Repository(repo, self._gitea) for repo in gitea_repos]
def get_subscriptions(self) -> List[Any]:
"""
Get repositories watched by the user.
Returns:
List of Repository objects
"""
# Import here to avoid circular imports
try:
# When running tests or using as a module
from models.repository import Repository
except ImportError:
# When using as a package
from .repository import Repository
# Get watched repos using Gitea API
gitea_repos = self._user.get_subscriptions()
# Convert to Repository objects
return [Repository(repo, self._gitea) for repo in gitea_repos]
def get_orgs(self) -> List[Dict[str, Any]]:
"""
Get organizations the user belongs to.
Returns:
List of organization objects
"""
gitea_orgs = self._user.get_orgs()
orgs = []
for org in gitea_orgs:
orgs.append({
'login': org.username,
'id': org.id,
'avatar_url': org.avatar_url,
'description': org.description,
'type': 'Organization'
})
return orgs
def get_followers(self) -> List['User']:
"""
Get users following this user.
Returns:
List of User objects
"""
gitea_followers = self._user.get_followers()
# Convert to User objects
return [User(follower, self._gitea) for follower in gitea_followers]
def get_following(self) -> List['User']:
"""
Get users this user is following.
Returns:
List of User objects
"""
gitea_following = self._user.get_following()
# Convert to User objects
return [User(user, self._gitea) for user in gitea_following]
def has_in_following(self, following: 'User') -> bool:
"""
Check if this user follows another user.
Args:
following: User to check
Returns:
True if following, False otherwise
"""
return self._user.is_following(following.login)
def add_to_following(self, following: 'User') -> None:
"""
Follow another user.
Args:
following: User to follow
"""
self._user.follow(following.login)
def remove_from_following(self, following: 'User') -> None:
"""
Unfollow another user.
Args:
following: User to unfollow
"""
self._user.unfollow(following.login)
def get_keys(self) -> List[Dict[str, Any]]:
"""
Get SSH keys for the user.
Returns:
List of key objects
"""
gitea_keys = self._user.get_keys()
keys = []
for key in gitea_keys:
keys.append({
'id': key.id,
'key': key.key,
'title': key.title,
'created_at': key.created_at,
'read_only': getattr(key, 'read_only', True)
})
return keys
def create_repo(self, name: str, **kwargs) -> Any:
"""
Create a new repository for the user.
Args:
name: Repository name
**kwargs: Additional parameters
Returns:
Repository object
"""
# Import here to avoid circular imports
try:
# When running tests or using as a module
from models.repository import Repository
except ImportError:
# When using as a package
from .repository import Repository
# Map GitHub parameters to Gitea parameters
gitea_params = {
'name': name,
'description': kwargs.get('description', ''),
'private': kwargs.get('private', False),
'auto_init': kwargs.get('auto_init', False),
'gitignores': kwargs.get('gitignore_template', ''),
'license': kwargs.get('license_template', ''),
'readme': kwargs.get('readme', '')
}
gitea_repo = self._user.create_repo(**gitea_params)
return Repository(gitea_repo, self._gitea)