import gradio as gr from github import Github, GithubException import os import requests import re # Załaduj token z pliku .env lub ustaw bezpośrednio GITHUB_TOKEN = os.getenv('GITHUB_TOKEN') g = Github(GITHUB_TOKEN) def get_file_content(owner, repo_name, path, branch="main"): url = f"https://raw.githubusercontent.com/{owner}/{repo_name}/{branch}/{path}" response = requests.get(url) if response.status_code == 200: return response.text else: return f"Błąd pobierania pliku: {response.status_code}" def extract_repo_info(url): """Wyodrębnia nazwę użytkownika i repozytorium z linku GitHub.""" match = re.search(r"github\.com/([^/]+)/([^/]+)", url) if match: return match.group(1), match.group(2) else: return None, None def github_tool( action: str, repo_name: str = None, branch: str = "main", # domyślna gałąź path: str = None, content: str = None, message: str = None, owner: str = None, vcs_url: str = None, title: str = None, body: str = None, base: str = None, head: str = None, issue_number: int = None, labels: str = None, # etykiety oddzielone przecinkami tag: str = None, name: str = None, # nazwa release file_url: str = None, # URL pliku do pobrania, repo_url: str = None, # Link do repozytorium ): """Narzędzie do zarządzania repozytoriami GitHub.""" user = g.get_user() try: if action == "import_repository": if not all([owner, repo_name, vcs_url]): raise ValueError( "Brakujące parametry: owner, repo_name, vcs_url") # Sprawdź, czy repozytorium już istnieje try: repo = user.get_repo(repo_name) return "Repozytorium o tej nazwie już istnieje." except GithubException: pass headers = { 'Authorization': f'token {GITHUB_TOKEN}', 'Accept': 'application/vnd.github.v3+json', } import_url = f'https://api.github.com/repos/{owner}/{repo_name}/import' payload = {'vcs_url': vcs_url, 'vcs': 'git'} response = requests.put(import_url, json=payload, headers=headers) if response.status_code == 201: return "Import repozytorium został rozpoczęty." else: return f"Błąd importu: {response.status_code}, {response.json()}" elif action == "create_repository": if not repo_name: raise ValueError("Brakujący parametr: repo_name") repo = user.create_repo(name=repo_name) return f"Repozytorium {repo_name} utworzone: {repo.html_url}" elif action == "create_file": if not all([repo_name, path, content, message]): raise ValueError( "Brakujące parametry: repo_name, path, content, message") repo = user.get_repo(repo_name) repo.create_file(path, message, content, branch=branch) return f"Plik {path} utworzony w {repo_name} na gałęzi {branch}" elif action == "get_file": if not all([repo_name, path]): raise ValueError("Brakujące parametry: repo_name, path") repo = user.get_repo(repo_name) file_content = repo.get_contents(path, ref=branch) return file_content.decoded_content.decode() # Zdekoduj zawartość pliku i zwróć jako string elif action == "get_file_content_by_url": if not file_url: raise ValueError("Brakujący parametr: file_url") response = requests.get(file_url) response.raise_for_status() # Sprawdź czy nie ma błędu HTTP return response.text elif action == "delete_file": if not all([repo_name, path]): raise ValueError("Brakujące parametry: repo_name, path") repo = user.get_repo(repo_name) file_contents = repo.get_contents(path, ref=branch) repo.delete_file(path, "Usunięcie pliku", file_contents.sha, branch=branch) return f"Plik {path} usunięty z {repo_name} na gałęzi {branch}" elif action == "update_file": if not all([repo_name, path, content, message]): raise ValueError( "Brakujące parametry: repo_name, path, content, message") repo = user.get_repo(repo_name) file_contents = repo.get_contents(path, ref=branch) repo.update_file(path, message, content, file_contents.sha, branch=branch) return f"Plik {path} zaktualizowany w {repo_name} na gałęzi {branch}" elif action == "list_branches": if not repo_name: raise ValueError("Brakujący parametr: repo_name") repo = user.get_repo(repo_name) branches = repo.get_branches() return [branch.name for branch in branches] elif action == "create_branch": if not all([repo_name, base, head]): # base jako źródło, head jako nowa nazwa raise ValueError("Brakujące parametry: repo_name, base, head") repo = user.get_repo(repo_name) source_branch = repo.get_branch(base) repo.create_git_ref(ref=f"refs/heads/{head}", sha=source_branch.commit.sha) return f"Gałąź {head} utworzona z {base} w {repo_name}" elif action == "delete_branch": if not all([repo_name, branch]): raise ValueError("Brakujące parametry: repo_name, branch") repo = user.get_repo(repo_name) repo.get_git_ref(f"heads/{branch}").delete() return f"Gałąź {branch} usunięta z {repo_name}" elif action == "create_pull_request": if not all([repo_name, title, body, base, head]): raise ValueError( "Brakujące parametry: repo_name, title, body, base, head") repo = user.get_repo(repo_name) pr = repo.create_pull(title=title, body=body, base=base, head=head) return f"Pull request utworzony: {pr.html_url}" elif action == "list_open_pull_requests": if not repo_name: raise ValueError("Brakujący parametr: repo_name") repo = user.get_repo(repo_name) open_prs = repo.get_pulls(state='open') return [{'title': pr.title, 'url': pr.html_url} for pr in open_prs] elif action == "create_issue": if not all([repo_name, title, body]): raise ValueError("Brakujące parametry: repo_name, title, body") repo = user.get_repo(repo_name) issue = repo.create_issue(title=title, body=body) return f"Issue utworzone: {issue.html_url}" elif action == "list_issues": if not repo_name: raise ValueError("Brakujący parametr: repo_name") repo = user.get_repo(repo_name) issues = repo.get_issues(state='open') return [{'title': issue.title, 'url': issue.html_url} for issue in issues] elif action == "add_label_to_issue": if not all([repo_name, issue_number, labels]): raise ValueError( "Brakujące parametry: repo_name, issue_number, labels") repo = user.get_repo(repo_name) issue = repo.get_issue(number=int(issue_number)) for label in labels.split(","): issue.add_to_labels(label.strip()) return f"Etykiety dodane do issue #{issue_number} w {repo_name}" elif action == "close_issue": if not all([repo_name, issue_number]): raise ValueError("Brakujące parametry: repo_name, issue_number") repo = user.get_repo(repo_name) issue = repo.get_issue(number=int(issue_number)) issue.edit(state='closed') return f"Issue #{issue_number} zamknięte w {repo_name}" elif action == "add_comment_to_issue": if not all([repo_name, issue_number, message]): # message jako treść komentarza raise ValueError( "Brakujące parametry: repo_name, issue_number, message") repo = user.get_repo(repo_name) issue = repo.get_issue(number=int(issue_number)) issue.create_comment(body=message) return f"Komentarz dodany do issue #{issue_number} w {repo_name}" elif action == "create_release": if not all([repo_name, tag, name, message]): raise ValueError( "Brakujące parametry: repo_name, tag, name, message") repo = user.get_repo(repo_name) release = repo.create_git_release( tag=tag, name=name, message=message) return f"Release {name} utworzone w {repo_name}: {release.html_url}" elif action == "list_releases": if not repo_name: raise ValueError("Brakujący parametr: repo_name") repo = user.get_repo(repo_name) releases = repo.get_releases() return [{'tag_name': release.tag_name, 'url': release.html_url} for release in releases] elif action == "fork_repository": if not repo_name: raise ValueError("Brakujący parametr: repo_name") repo = g.get_repo(repo_name) # Pobierz repozytorium do forkowania fork = user.create_fork(repo) return f"Fork repozytorium utworzony: {fork.html_url}" elif action == "list_forks": if not repo_name: raise ValueError("Brakujący parametr: repo_name") repo = g.get_repo(repo_name) # Pobierz repo, którego forki chcesz wyświetlić forks = repo.get_forks() return [{'full_name': fork.full_name, 'url': fork.html_url} for fork in forks] elif action == "list_files": if not all([owner, repo_name]): raise ValueError("Brakujące parametry: owner, repo_name") repo = g.get_repo(f"{owner}/{repo_name}") # Dodaj obsługę pustej ścieżki: if not path: contents = repo.get_contents("") # Pobierz zawartość głównego katalogu else: contents = repo.get_contents(path) files = [{'name': content.name, 'path': content.path, 'download_url': content.download_url} for content in contents] return files elif action == "get_repository_info": if not all([owner, repo_name]): raise ValueError("Brakujące parametry: owner, repo_name") repo = g.get_repo(f"{owner}/{repo_name}") info = { "nazwa": repo.name, "opis": repo.description, "url": repo.html_url, "właściciel": repo.owner.login, "gałąź domyślna": repo.default_branch, "język": repo.language, "liczba gwiazdek": repo.stargazers_count, "liczba forków": repo.forks_count, "utworzone": repo.created_at, "ostatnia aktualizacja": repo.updated_at } return info # Zwraca słownik z informacjami elif action == "get_file_content": if not all([owner, repo_name, path]): raise ValueError("Brakujące parametry: owner, repo_name, path") return get_file_content(owner, repo_name, path, branch) elif action == "analyze_repository_by_url": if not repo_url: raise ValueError("Brakujący parametr: repo_url") owner, repo_name = extract_repo_info(repo_url) if not owner or not repo_name: raise ValueError("Nieprawidłowy link do repozytorium") try: repo = g.get_repo(f"{owner}/{repo_name}") # Pobierz listę plików i katalogów contents = repo.get_contents("") # Iteruj po liście i pobieraj zawartość plików file_analyses = [] for content in contents: if content.type == "file": file_content = content.decoded_content.decode() file_analyses.append({ "name": content.name, "path": content.path, "content": file_content, # Możesz dodać tutaj analizę zawartości pliku }) return file_analyses except GithubException as e: return f"Błąd GitHub: {str(e)}" elif action == "analyze_repository_content": if not all([owner, repo_name]): raise ValueError("Brakujące parametry: owner, repo_name") try: repo = g.get_repo(f"{owner}/{repo_name}") # Pobierz listę plików i katalogów contents = repo.get_contents("") file_analyses = [] # Iteruj po liście i pobieraj zawartość plików for content in contents: if content.type == "file": file_content = get_file_content(owner, repo_name, content.path, branch) file_analyses.append({ "name": content.name, "path": content.path, "content": file_content, }) return file_analyses except GithubException as e: return f"Błąd GitHub: {str(e)}" else: raise ValueError(f"Nieznana akcja: {action}") except GithubException as e: return f"Błąd GitHub: {str(e)}" except ValueError as e: return f"Błąd: {str(e)}" with gr.Blocks() as demo: with gr.Row(): action = gr.Dropdown( choices=[ "import_repository", "create_repository", "create_file", "get_file", "get_file_content_by_url", "delete_file", "update_file", "list_branches", "create_branch", "delete_branch", "create_pull_request", "list_open_pull_requests", "create_issue", "list_issues", "add_label_to_issue", "close_issue", "add_comment_to_issue", "create_release", "list_releases", "fork_repository", "list_forks", "list_files", "get_repository_info", "get_file_content", "analyze_repository_by_url", "analyze_repository_content", # Nowa akcja ], label="Akcja", ) repo_name = gr.Textbox(label="Nazwa repozytorium") branch = gr.Textbox(label="Gałąź", value="main") path = gr.Textbox(label="Ścieżka do pliku") content = gr.Textbox(label="Zawartość pliku") message = gr.Textbox(label="Wiadomość/Komentarz") owner = gr.Textbox(label="Właściciel") vcs_url = gr.Textbox(label="URL VCS") title = gr.Textbox(label="Tytuł") body = gr.Textbox(label="Treść") base = gr.Textbox(label="Gałąź bazowa") head = gr.Textbox(label="Gałąź docelowa/Nowa gałąź") issue_number = gr.Number(label="Numer issue", precision=0) labels = gr.Textbox(label="Etykiety (oddzielone przecinkami)") tag = gr.Textbox(label="Tag") release_name = gr.Textbox(label="Nazwa release") # Zmieniona nazwa file_url = gr.Textbox(label="URL pliku") # Dodane pole repo_url = gr.Textbox(label="Link do repozytorium") # Dodane pole with gr.Row(): run_button = gr.Button("Wykonaj") output = gr.Textbox(label="Wynik") run_button.click( github_tool, inputs=[ action, repo_name, branch, path, content, message, owner, vcs_url, title, body, base, head, issue_number, labels, tag, release_name, # Użycie zmienionej nazwy file_url, # Dodany argument repo_url, # Dodany argument ], outputs=output, api_name="github_tool" ) demo.launch()