pr_manager/apps/pr/views.py

116 lines
4.2 KiB
Python

import json
from pr import models
from django.views import View
from django.http import JsonResponse
from utils.pr_agent import cli
from utils.pr_agent.config_loader import get_settings
from utils import constant
def load_project_config(
git_url,
access_token,
project_secret,
openai_api_base,
openai_key,
llm_model
):
"""
加载项目配置
:param git_url: git服务器地址
:param access_token: 用户访问密钥
:param project_secret: 项目秘钥
:param openai_api_base: openai api base
:param openai_key: openai key
:param llm_model: llm model
:return:
"""
return {
"gitlab_url": git_url,
"access_token": access_token,
"secret": project_secret,
"openai_api_base": openai_api_base,
"openai_key": openai_key,
"llm_model": llm_model
}
class WebHookView(View):
def post(self, request):
data = json.loads(request.body.decode('utf-8'))
if not data:
return JsonResponse(status=400, data={"error": "Invalid JSON"})
project_id = data.get('project', {}).get('id') or data.get('project_id')
if not project_id:
return JsonResponse(status=400, data={"error": "Missing project ID"})
project_config = models.ProjectConfig.objects.filter(project_id=project_id).first()
# AI模型配置
api_base = project_config.git_config.pr_ai.api_base
api_key = project_config.git_config.pr_ai.api_key
model = project_config.git_config.pr_ai.llm_model
# Git服务器配置
git_url = project_config.git_config.git_url
git_type = constant.GIT_TYPE[project_config.git_config.git_type][1]
access_token = project_config.git_config.access_token
project_secret = project_config.project_secret
project_commands = project_config.commands.split(",")
config = load_project_config(
git_url=git_url,
access_token=access_token,
project_secret=project_secret,
openai_api_base=api_base,
openai_key=api_key,
llm_model=model
)
token = request.headers.get('X-Gitlab-Token')
if token:
token = token.strip()
expected_token = config["secret"].strip() if config["secret"] else None
if token != expected_token:
return JsonResponse(status=403, data={"error": "Invalid token"})
# 处理Merge Request事件
if data.get('object_kind') == 'merge_request':
merge_request = data.get('object_attributes', {})
if merge_request.get('state') == 'opened':
# 获取Merge Request的详细信息
mr_url = merge_request.get('url')
mr_action = merge_request.get('action')
get_settings().set("config.git_provider", git_type)
get_settings().set("gitlab.url", git_url)
get_settings().set("gitlab.personal_access_token", access_token)
get_settings().set("openai.api_base", api_base)
get_settings().set("openai.key", api_key)
get_settings().set("llm.model", model)
if mr_action == "update":
old_rev = merge_request.get("oldrev")
new_rev = merge_request.get("newrev")
if old_rev == new_rev:
return JsonResponse(status=200, data={"status": "ignored (no code change)"})
import threading
def run_cmd(command):
cli.run_command(mr_url, command)
threads = []
for cmd in project_commands:
if cmd not in [cmd[1] for cmd in constant.DEFAULT_COMMANDS]:
continue
t = threading.Thread(target=run_cmd, args=(cmd,))
threads.append(t)
t.start()
# 记录MR信息
return JsonResponse(status=200, data={"status": "review started"})
return JsonResponse(status=400, data={"error": "Merge request URL not found or action not open"})
return JsonResponse(status=200, data={"status": "ignored"})