From acd4a5f7074c6f4351f891ed42093fa7f753fb8c Mon Sep 17 00:00:00 2001 From: Steve White Date: Mon, 14 Apr 2025 10:46:22 -0500 Subject: [PATCH] Added list-repos and search-repos commands with advanced filtering --- README.md | 41 ++++++++++-- gitea_cli.py | 177 +++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 192 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 776c8f8..4913276 100644 --- a/README.md +++ b/README.md @@ -45,8 +45,39 @@ If you're in a git repository and want to create a new Gitea repository and set python gitea_cli.py create-repo --name my-repo --description "My new repository" --set-remote ``` -This will: -1. Create a new repository on Gitea -2. Check if the current directory is a git repository -3. Remove any existing 'origin' remote -4. Add the new Gitea repository as 'origin' +### List repositories for a user: +```bash +python gitea_cli.py list-repos --user USERNAME +``` + +With pagination: +```bash +python gitea_cli.py list-repos --user USERNAME --page 2 --limit 50 +``` + +### Search repositories: +Basic name search: +```bash +python gitea_cli.py search-repos --user USERNAME --query "search term" +``` + +Search descriptions: +```bash +python gitea_cli.py search-repos --user USERNAME --query "term" --search-in description +``` + +Filter by private status: +```bash +python gitea_cli.py search-repos --user USERNAME --private true +``` + +Combined search with pagination: +```bash +python gitea_cli.py search-repos --user USERNAME --query "project" --search-in both --private false --page 2 --limit 50 +``` + +### Toggle repository visibility: +```bash +python gitea_cli.py mode --name REPO_NAME --public +python gitea_cli.py mode --name REPO_NAME --private +``` diff --git a/gitea_cli.py b/gitea_cli.py index 3a962d3..a3e921f 100755 --- a/gitea_cli.py +++ b/gitea_cli.py @@ -45,6 +45,60 @@ class GiteaAPI: else: response.raise_for_status() + def list_user_repositories(self, username, page=1, limit=30): + """List repositories for a specific user. + + Args: + username: The user to list repositories for + page: Page number (default: 1) + limit: Items per page (default: 30, max: 50) + """ + endpoint = f"{self.base_url}/api/v1/users/{username}/repos" + params = { + 'page': page, + 'limit': min(limit, 50) # Gitea's max limit is 50 + } + response = self.session.get(endpoint, params=params) + if response.status_code == 200: + return response.json() + else: + response.raise_for_status() + + def search_user_repositories(self, username, query=None, private=None, + search_in='name', page=1, limit=30): + """Search repositories for a specific user with advanced filters. + + Args: + username: The user to search repositories for + query: Optional search term (searches name/description) + private: Optional filter by private status (True/False) + search_in: Where to search ('name', 'description', or 'both') + page: Page number (default: 1) + limit: Items per page (default: 30, max: 50) + """ + endpoint = f"{self.base_url}/api/v1/repos/search" + params = { + 'uid': username, + 'page': page, + 'limit': min(limit, 50) + } + + if query: + if search_in == 'name': + params['q'] = query + elif search_in == 'description': + params['q'] = f'description:{query}' + else: # both - search all fields + params['q'] = query + + if private is not None: + params['private'] = 'true' if private else 'false' + response = self.session.get(endpoint, params=params) + if response.status_code == 200: + return response.json().get('data', []) + else: + response.raise_for_status() + def get_gitea_config(url=None, token=None): """Get Gitea configuration from environment or command line arguments.""" config = { @@ -107,27 +161,13 @@ def set_git_remote(repo_url): def cli(): """Gitea CLI - Command line interface for Gitea - Configuration can be provided in two ways: - 1. Environment variables: - - GITEA_URL: Your Gitea server URL - - GITEA_TOKEN: Your Gitea API token - - 2. Command line arguments: - --gitea-url: Your Gitea server URL (overrides GITEA_URL) - --gitea-token: Your Gitea API token (overrides GITEA_TOKEN) - Commands: - create-repo: Create a new repository on Gitea - Flags: - --name: Repository name (required) - --description: Repository description - --private: Create repository as private - --set-remote: Set git remote 'origin' to new repository - mode: Toggle repository visibility between public and private - Flags: - --name: Repository name (required) - --public: Set repository to public - --private: Set repository to private + create-repo: Create a new repository + list-repos: List user repositories + search-repos: Search repositories with filters + mode: Toggle repository visibility + + Run 'gitea_cli.py COMMAND --help' for details. """ pass @@ -203,5 +243,100 @@ def mode(name, public, private): except Exception as e: click.echo(f"Error: {str(e)}") +@cli.command() +@click.option('--user', required=True, help='Username to list repositories for') +@click.option('--page', default=1, help='Page number (default: 1)') +@click.option('--limit', default=30, help='Items per page (default: 30, max: 50)') +@click.option('--gitea-url', + help='Gitea server URL (overrides GITEA_URL environment variable)') +@click.option('--gitea-token', + help='Gitea API token (overrides GITEA_TOKEN environment variable)') +def list_repos(user, page, limit, gitea_url, gitea_token): + """List repositories for a specific user. + + Examples: + $ gitea_cli.py list-repos --user stwhite + $ gitea_cli.py list-repos --user stwhite --page 2 --limit 50 + """ + config = get_gitea_config(gitea_url, gitea_token) + + try: + gitea = GiteaAPI(config['url'], config['token']) + repos = gitea.list_user_repositories(user, page=page, limit=limit) + + if not repos: + click.echo(f"No repositories found for user: {user}") + return + + click.echo(f"Repositories for {user}:") + for repo in repos: + visibility = "private" if repo['private'] else "public" + click.echo(f"- {repo['name']} ({visibility}): {repo['html_url']}") + + except requests.exceptions.RequestException as e: + click.echo(f"Error listing repositories: {str(e)}") + sys.exit(1) + +@cli.command() +@click.option('--user', required=True, help='Username to search repositories for') +@click.option('--query', help='Search term (searches name by default)') +@click.option('--private', type=bool, help='Filter by private status (true/false)') +@click.option('--search-in', default='name', + type=click.Choice(['name', 'description', 'both']), + help='Where to search (name/description/both)') +@click.option('--page', default=1, help='Page number (default: 1)') +@click.option('--limit', default=30, help='Items per page (default: 30, max: 50)') +@click.option('--gitea-url', + help='Gitea server URL (overrides GITEA_URL environment variable)') +@click.option('--gitea-token', + help='Gitea API token (overrides GITEA_TOKEN environment variable)') +def search_repos(user, query, private, search_in, page, limit, gitea_url, gitea_token): + """Search repositories for a specific user with advanced filters. + + Examples: + # Basic name search + $ gitea_cli.py search-repos --user stwhite --query paper + + # Search descriptions + $ gitea_cli.py search-repos --user stwhite --query "research" --search-in description + + # Filter private repos + $ gitea_cli.py search-repos --user stwhite --private true + + # Combined search with pagination + $ gitea_cli.py search-repos --user stwhite --query project --search-in both --private false --page 2 --limit 50 + """ + config = get_gitea_config(gitea_url, gitea_token) + + try: + gitea = GiteaAPI(config['url'], config['token']) + repos = gitea.search_user_repositories( + user, + query=query, + private=private, + search_in=search_in, + page=page, + limit=limit + ) + + if not repos: + msg = f"No repositories found" + if query: + msg += f" matching '{query}'" + if private is not None: + msg += f" (private: {private})" + msg += f" for user: {user}" + click.echo(msg) + return + + click.echo(f"Repositories matching '{query}' for {user}:") + for repo in repos: + visibility = "private" if repo['private'] else "public" + click.echo(f"- {repo['name']} ({visibility}): {repo['html_url']}") + + except requests.exceptions.RequestException as e: + click.echo(f"Error searching repositories: {str(e)}") + sys.exit(1) + if __name__ == '__main__': - cli() \ No newline at end of file + cli()