import base64 import requests from urllib.parse import urlparse def split_link(repo_link): """Разбирает ссылку вида https://gitea.com/user/repo.""" repo_link = repo_link.strip().rstrip("/") parsed = urlparse(repo_link) if not parsed.scheme or not parsed.netloc: raise ValueError("Введите полную ссылку, например: https://gitea.com/user/repo") parts = [p for p in parsed.path.split("/") if p] if len(parts) < 2: raise ValueError("Ссылка должна быть вида: https://site/user/repo") base_url = f"{parsed.scheme}://{parsed.netloc}" owner = parts[0] repo = parts[1] return base_url, owner, repo def _get_json(url): response = requests.get(url, timeout=15) if response.status_code != 200: raise Exception(f"Ошибка запроса: {response.status_code}\n{url}") return response.json() def get_repo_data(repo_link): base_url, owner, repo = split_link(repo_link) url = f"{base_url}/api/v1/repos/{owner}/{repo}" return _get_json(url) def get_commits(repo_link): base_url, owner, repo = split_link(repo_link) url = f"{base_url}/api/v1/repos/{owner}/{repo}/commits" data = _get_json(url) if isinstance(data, list): return data return [] def get_code_lines(repo_link): """Считает строки Python-кода в ветке main/master.""" base_url, owner, repo = split_link(repo_link) total_lines = 0 # У разных репозиториев может быть main или master. for branch in ("main", "master"): tree_url = f"{base_url}/api/v1/repos/{owner}/{repo}/git/trees/{branch}?recursive=1" try: data = _get_json(tree_url) break except Exception: data = None if not data: return 0 for file in data.get("tree", []): if file.get("type") != "blob": continue path = file.get("path", "") if not path.endswith(".py"): continue file_url = f"{base_url}/api/v1/repos/{owner}/{repo}/contents/{path}" try: file_data = _get_json(file_url) content = file_data.get("content") if content: decoded = base64.b64decode(content).decode("utf-8", errors="ignore") total_lines += len(decoded.splitlines()) except Exception: continue return total_lines