251 lines
8.0 KiB
Python
251 lines
8.0 KiB
Python
"""Main shim class that provides GitHub-compatible interface for Gitea."""
|
|
|
|
import os
|
|
from typing import Optional, Dict, Any, List
|
|
|
|
try:
|
|
# When running tests or using as a module
|
|
from models.repository import Repository
|
|
from models.user import User
|
|
from models.pull_request import PullRequest
|
|
except ImportError:
|
|
# When using as a package
|
|
from .models.repository import Repository
|
|
from .models.user import User
|
|
from .models.pull_request import PullRequest
|
|
|
|
# Mock the Gitea import for testing
|
|
try:
|
|
from gitea import Gitea
|
|
except ImportError:
|
|
# Mock Gitea for testing purposes
|
|
class Gitea:
|
|
def __init__(self, url, token):
|
|
self.url = url
|
|
self.token = token
|
|
|
|
|
|
class GiteaGitHubShim:
|
|
"""
|
|
A shim class that provides a GitHub-compatible interface for Gitea.
|
|
|
|
This class mimics the PyGitHub's Github class API, translating calls
|
|
to the py-gitea SDK.
|
|
"""
|
|
|
|
def __init__(self, base_url_or_token: Optional[str] = None,
|
|
base_url: Optional[str] = None,
|
|
timeout: int = 60,
|
|
per_page: int = 30):
|
|
"""
|
|
Initialize the Gitea client with GitHub-compatible interface.
|
|
|
|
Args:
|
|
base_url_or_token: If only one arg provided, treated as token (GitHub compat)
|
|
base_url: The Gitea instance URL
|
|
timeout: Request timeout in seconds
|
|
per_page: Number of items per page for pagination
|
|
"""
|
|
# Handle GitHub-style initialization where only token is provided
|
|
if base_url is None and base_url_or_token:
|
|
# In GitHub mode, we expect GITEA_URL to be set
|
|
self.token = base_url_or_token
|
|
self.base_url = os.getenv('GITEA_URL', 'http://localhost:3000')
|
|
else:
|
|
self.token = base_url_or_token
|
|
self.base_url = base_url or os.getenv('GITEA_URL', 'http://localhost:3000')
|
|
|
|
# Remove trailing slash from base URL
|
|
self.base_url = self.base_url.rstrip('/')
|
|
|
|
# Initialize the Gitea client
|
|
self._gitea = Gitea(self.base_url, self.token)
|
|
self.timeout = timeout
|
|
self.per_page = per_page
|
|
|
|
def get_repo(self, full_name_or_id: str) -> Repository:
|
|
"""
|
|
Get a repository by its full name (owner/repo) or ID.
|
|
|
|
Args:
|
|
full_name_or_id: Repository full name (owner/repo) or ID
|
|
|
|
Returns:
|
|
Repository object with GitHub-compatible interface
|
|
"""
|
|
if '/' in str(full_name_or_id):
|
|
# It's a full name (owner/repo)
|
|
owner, repo_name = full_name_or_id.split('/', 1)
|
|
try:
|
|
gitea_repo = self._gitea.get_repo(owner, repo_name)
|
|
except Exception as e:
|
|
# Handle case where repo doesn't exist
|
|
raise Exception(f"Repository {full_name_or_id} not found: {str(e)}")
|
|
else:
|
|
# It's an ID - Gitea doesn't support this directly
|
|
# We'd need to implement a search or listing mechanism
|
|
raise NotImplementedError("Getting repository by ID is not yet supported")
|
|
|
|
return Repository(gitea_repo, self._gitea)
|
|
|
|
def get_user(self, login: Optional[str] = None) -> User:
|
|
"""
|
|
Get a user by login name or get the authenticated user.
|
|
|
|
Args:
|
|
login: Username to get. If None, returns authenticated user.
|
|
|
|
Returns:
|
|
User object with GitHub-compatible interface
|
|
"""
|
|
if login is None:
|
|
# Get authenticated user
|
|
gitea_user = self._gitea.get_user()
|
|
else:
|
|
# Get specific user
|
|
gitea_user = self._gitea.get_user(login)
|
|
|
|
return User(gitea_user, self._gitea)
|
|
|
|
def get_organization(self, login: str):
|
|
"""
|
|
Get an organization by login name.
|
|
|
|
Args:
|
|
login: Organization name
|
|
|
|
Returns:
|
|
Organization object (not yet implemented)
|
|
"""
|
|
# Organizations in Gitea are similar to GitHub
|
|
gitea_org = self._gitea.get_org(login)
|
|
# TODO: Implement Organization model
|
|
return gitea_org
|
|
|
|
def create_repo(self, name: str, **kwargs) -> Repository:
|
|
"""
|
|
Create a new repository.
|
|
|
|
Args:
|
|
name: Repository name
|
|
**kwargs: Additional parameters (description, private, etc.)
|
|
|
|
Returns:
|
|
Repository object
|
|
"""
|
|
# 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._gitea.create_repo(**gitea_params)
|
|
return Repository(gitea_repo, self._gitea)
|
|
|
|
def get_api_status(self) -> Dict[str, Any]:
|
|
"""Get API status information."""
|
|
# Gitea doesn't have a direct equivalent, return version info
|
|
try:
|
|
version = self._gitea.get_version()
|
|
return {
|
|
'status': 'good',
|
|
'version': version,
|
|
'api': 'gitea'
|
|
}
|
|
except Exception:
|
|
return {
|
|
'status': 'unknown',
|
|
'version': 'unknown',
|
|
'api': 'gitea'
|
|
}
|
|
|
|
def get_rate_limit(self) -> Dict[str, Any]:
|
|
"""
|
|
Get rate limit information.
|
|
|
|
Note: Gitea doesn't have rate limiting like GitHub, so we return
|
|
mock data indicating no limits.
|
|
"""
|
|
return {
|
|
'rate': {
|
|
'limit': 999999,
|
|
'remaining': 999999,
|
|
'reset': 0
|
|
}
|
|
}
|
|
|
|
def search_repositories(self, query: str, **kwargs) -> List[Repository]:
|
|
"""
|
|
Search repositories.
|
|
|
|
Args:
|
|
query: Search query
|
|
**kwargs: Additional search parameters
|
|
|
|
Returns:
|
|
List of Repository objects
|
|
"""
|
|
# Gitea search might have different parameters
|
|
gitea_repos = self._gitea.search_repos(query, **kwargs)
|
|
return [Repository(repo, self._gitea) for repo in gitea_repos]
|
|
|
|
def search_users(self, query: str, **kwargs) -> List[User]:
|
|
"""
|
|
Search users.
|
|
|
|
Args:
|
|
query: Search query
|
|
**kwargs: Additional search parameters
|
|
|
|
Returns:
|
|
List of User objects
|
|
"""
|
|
gitea_users = self._gitea.search_users(query, **kwargs)
|
|
return [User(user, self._gitea) for user in gitea_users]
|
|
|
|
def get_emojis(self) -> Dict[str, str]:
|
|
"""
|
|
Get available emojis.
|
|
|
|
Note: Gitea might not support this, return empty dict
|
|
"""
|
|
return {}
|
|
|
|
def get_gitignore_templates(self) -> List[str]:
|
|
"""
|
|
Get available gitignore templates.
|
|
|
|
Returns:
|
|
List of template names
|
|
"""
|
|
try:
|
|
templates = self._gitea.get_gitignore_templates()
|
|
return [t.name for t in templates]
|
|
except Exception:
|
|
return []
|
|
|
|
def get_license_templates(self) -> List[Dict[str, Any]]:
|
|
"""
|
|
Get available license templates.
|
|
|
|
Returns:
|
|
List of license template objects
|
|
"""
|
|
try:
|
|
licenses = self._gitea.get_license_templates()
|
|
return [
|
|
{
|
|
'key': lic.key,
|
|
'name': lic.name,
|
|
'url': lic.url,
|
|
'spdx_id': lic.spdx_id
|
|
}
|
|
for lic in licenses
|
|
]
|
|
except Exception:
|
|
return [] |