Add gitea-shim integration and update workflow services
This commit is contained in:
251
gitea-shim/python/gitea_github_shim.py
Normal file
251
gitea-shim/python/gitea_github_shim.py
Normal file
@ -0,0 +1,251 @@
|
||||
"""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 []
|
Reference in New Issue
Block a user