forked from Lesin/reposync
[Sync] [Sync] 双向合并测试 #3
|
|
@ -75,6 +75,6 @@ workflow:
|
|||
ssh_ip: '"114.55.175.219"'
|
||||
ssh_port: '"22"'
|
||||
ssh_user: '"root"'
|
||||
ssh_cmd: '"echo \"🚀 启动Issue同步服务...\" && docker exec group_03_01 pkill -f issue_sync_web.py || true && sleep 2 && docker exec group_03_01 bash -c \"cd /app && nohup python -u issue_sync_web.py > /tmp/issue_sync.log 2>&1 &\" && sleep 5 && echo \"📋 检查进程状态...\" && docker exec group_03_01 ps aux | grep -v grep | grep issue_sync_web || echo \"❌ 进程未找到\" && echo \"🔍 检查端口监听...\" && docker exec group_03_01 netstat -tlnp | grep 8001 || echo \"❌ 端口未监听\" && echo \"📖 检查日志...\" && docker exec group_03_01 tail -10 /tmp/issue_sync.log && echo \"📖 API文档地址: http://114.55.175.219:8001/docs\" && echo \"🔍 服务状态地址: http://114.55.175.219:8001/status\" && echo \"🧪 测试本地连接...\" && docker exec group_03_01 curl -s http://localhost:8001/status || echo \"⚠️ 本地连接失败\""'
|
||||
needs:
|
||||
ssh_cmd: '"docker exec -d group_03_01 python issue_sync_web_simple.py"'
|
||||
needs:
|
||||
- configure_firewall
|
||||
|
|
@ -0,0 +1,268 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
简化版Issue同步Web服务 - 兼容老版本Python
|
||||
"""
|
||||
|
||||
import time
|
||||
import sys
|
||||
import os
|
||||
import json
|
||||
import threading
|
||||
from wsgiref.simple_server import make_server
|
||||
|
||||
# 添加issue_sync_module到Python路径
|
||||
issue_sync_path = os.path.join(os.path.dirname(__file__), 'issue_sync_module')
|
||||
if issue_sync_path not in sys.path:
|
||||
sys.path.append(issue_sync_path)
|
||||
|
||||
# 尝试导入依赖
|
||||
try:
|
||||
from clients.sync_service import IssueSyncService
|
||||
DEPENDENCIES_AVAILABLE = True
|
||||
print("✅ Issue同步服务依赖可用")
|
||||
except ImportError as e:
|
||||
print("⚠️ Issue同步服务依赖不可用: {}".format(str(e)))
|
||||
DEPENDENCIES_AVAILABLE = False
|
||||
|
||||
# 简单的HTTP响应函数
|
||||
def json_response(data, status='200 OK'):
|
||||
"""返回JSON响应"""
|
||||
response_data = json.dumps(data, ensure_ascii=False, indent=2)
|
||||
headers = [
|
||||
('Content-Type', 'application/json; charset=utf-8'),
|
||||
('Content-Length', str(len(response_data.encode('utf-8')))),
|
||||
('Access-Control-Allow-Origin', '*'),
|
||||
('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'),
|
||||
('Access-Control-Allow-Headers', 'Content-Type')
|
||||
]
|
||||
return status, headers, response_data
|
||||
|
||||
def parse_post_data(environ):
|
||||
"""解析POST数据"""
|
||||
try:
|
||||
content_length = int(environ.get('CONTENT_LENGTH', 0))
|
||||
if content_length > 0:
|
||||
post_data = environ['wsgi.input'].read(content_length)
|
||||
return json.loads(post_data.decode('utf-8'))
|
||||
except:
|
||||
pass
|
||||
return {}
|
||||
|
||||
def execute_sync_task(sync_method, source_org, source_repo, target_org, target_repo, sync_comments=False):
|
||||
"""执行同步任务"""
|
||||
try:
|
||||
print("🚀 开始执行Issue同步: {}/{} → {}/{}".format(source_org, source_repo, target_org, target_repo))
|
||||
|
||||
# 检查同步方法是否支持评论同步参数
|
||||
import inspect
|
||||
try:
|
||||
sig = inspect.signature(sync_method)
|
||||
if 'sync_comments' in sig.parameters:
|
||||
result = sync_method(source_org, source_repo, target_org, target_repo, sync_comments)
|
||||
else:
|
||||
result = sync_method(source_org, source_repo, target_org, target_repo)
|
||||
except AttributeError:
|
||||
# 老版本Python没有inspect.signature,直接尝试调用
|
||||
try:
|
||||
result = sync_method(source_org, source_repo, target_org, target_repo, sync_comments)
|
||||
except TypeError:
|
||||
result = sync_method(source_org, source_repo, target_org, target_repo)
|
||||
|
||||
if result:
|
||||
print("✅ Issue同步成功: {}/{} → {}/{}".format(source_org, source_repo, target_org, target_repo))
|
||||
else:
|
||||
print("❌ Issue同步失败: {}/{} → {}/{}".format(source_org, source_repo, target_org, target_repo))
|
||||
|
||||
except Exception as e:
|
||||
print("💥 Issue同步任务执行异常: {}".format(str(e)))
|
||||
|
||||
def get_sync_method(sync_service, source_platform, target_platform):
|
||||
"""根据平台获取对应的同步方法"""
|
||||
sync_mapping = {
|
||||
('github', 'gitee'): sync_service.sync_github_to_gitee,
|
||||
('gitee', 'github'): sync_service.sync_gitee_to_github,
|
||||
('gitlink', 'github'): sync_service.sync_gitlink_to_github,
|
||||
('gitlink', 'gitee'): sync_service.sync_gitlink_to_gitee,
|
||||
('github', 'gitlink'): sync_service.sync_github_to_gitlink,
|
||||
('gitee', 'gitlink'): sync_service.sync_gitee_to_gitlink,
|
||||
}
|
||||
|
||||
return sync_mapping.get((source_platform, target_platform))
|
||||
|
||||
def application(environ, start_response):
|
||||
"""WSGI应用程序"""
|
||||
path = environ['PATH_INFO']
|
||||
method = environ['REQUEST_METHOD']
|
||||
|
||||
# 处理CORS预检请求
|
||||
if method == 'OPTIONS':
|
||||
status, headers, data = json_response({})
|
||||
start_response(status, headers)
|
||||
return [data.encode('utf-8')]
|
||||
|
||||
# 路由处理
|
||||
if path == '/' and method == 'GET':
|
||||
# 根路径
|
||||
data = {
|
||||
"service": "Issue同步服务(简化版)",
|
||||
"version": "1.0.0",
|
||||
"status": "运行中",
|
||||
"dependencies_available": DEPENDENCIES_AVAILABLE,
|
||||
"endpoints": {
|
||||
"status": "/status",
|
||||
"sync": "/sync"
|
||||
}
|
||||
}
|
||||
status, headers, response_data = json_response(data)
|
||||
start_response(status, headers)
|
||||
return [response_data.encode('utf-8')]
|
||||
|
||||
elif path == '/status' and method == 'GET':
|
||||
# 状态检查
|
||||
data = {
|
||||
"success": True,
|
||||
"data": {
|
||||
"service_available": DEPENDENCIES_AVAILABLE,
|
||||
"supported_platforms": ["github", "gitee", "gitlink"],
|
||||
"supported_directions": [
|
||||
"github → gitee",
|
||||
"gitee → github",
|
||||
"gitlink → github",
|
||||
"gitlink → gitee",
|
||||
"github → gitlink",
|
||||
"gitee → gitlink"
|
||||
],
|
||||
"timestamp": time.strftime('%Y-%m-%d %H:%M:%S')
|
||||
},
|
||||
"message": "服务状态获取成功"
|
||||
}
|
||||
status, headers, response_data = json_response(data)
|
||||
start_response(status, headers)
|
||||
return [response_data.encode('utf-8')]
|
||||
|
||||
elif path == '/sync' and method == 'POST':
|
||||
# Issue同步
|
||||
post_data = parse_post_data(environ)
|
||||
|
||||
try:
|
||||
if not DEPENDENCIES_AVAILABLE:
|
||||
data = {
|
||||
"success": False,
|
||||
"message": "Issue同步服务依赖不可用",
|
||||
"timestamp": time.strftime('%Y-%m-%d %H:%M:%S')
|
||||
}
|
||||
status, headers, response_data = json_response(data)
|
||||
start_response(status, headers)
|
||||
return [response_data.encode('utf-8')]
|
||||
|
||||
# 验证必要参数
|
||||
required_fields = ['source_org', 'source_repo', 'source_platform',
|
||||
'target_org', 'target_repo', 'target_platform']
|
||||
|
||||
for field in required_fields:
|
||||
if not post_data.get(field):
|
||||
data = {
|
||||
"success": False,
|
||||
"message": "缺少必要参数: {}".format(field),
|
||||
"timestamp": time.strftime('%Y-%m-%d %H:%M:%S')
|
||||
}
|
||||
status, headers, response_data = json_response(data)
|
||||
start_response(status, headers)
|
||||
return [response_data.encode('utf-8')]
|
||||
|
||||
# 验证平台类型
|
||||
valid_platforms = ["github", "gitee", "gitlink"]
|
||||
source_platform = post_data['source_platform']
|
||||
target_platform = post_data['target_platform']
|
||||
|
||||
if source_platform not in valid_platforms or target_platform not in valid_platforms:
|
||||
data = {
|
||||
"success": False,
|
||||
"message": "不支持的平台类型。支持的平台: {}".format(valid_platforms),
|
||||
"timestamp": time.strftime('%Y-%m-%d %H:%M:%S')
|
||||
}
|
||||
status, headers, response_data = json_response(data)
|
||||
start_response(status, headers)
|
||||
return [response_data.encode('utf-8')]
|
||||
|
||||
# 创建同步服务
|
||||
sync_service = IssueSyncService()
|
||||
|
||||
# 根据平台组合执行同步
|
||||
sync_method = get_sync_method(sync_service, source_platform, target_platform)
|
||||
if not sync_method:
|
||||
data = {
|
||||
"success": False,
|
||||
"message": "不支持的同步方向: {} → {}".format(source_platform, target_platform),
|
||||
"timestamp": time.strftime('%Y-%m-%d %H:%M:%S')
|
||||
}
|
||||
status, headers, response_data = json_response(data)
|
||||
start_response(status, headers)
|
||||
return [response_data.encode('utf-8')]
|
||||
|
||||
# 在后台线程执行同步
|
||||
sync_comments = post_data.get('sync_comments', False)
|
||||
thread = threading.Thread(
|
||||
target=execute_sync_task,
|
||||
args=(sync_method, post_data['source_org'], post_data['source_repo'],
|
||||
post_data['target_org'], post_data['target_repo'], sync_comments)
|
||||
)
|
||||
thread.daemon = True
|
||||
thread.start()
|
||||
|
||||
data = {
|
||||
"success": True,
|
||||
"message": "Issue同步任务已启动: {} → {}".format(source_platform, target_platform),
|
||||
"timestamp": time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
"task_info": {
|
||||
"source": "{}/{}".format(post_data['source_org'], post_data['source_repo']),
|
||||
"target": "{}/{}".format(post_data['target_org'], post_data['target_repo']),
|
||||
"sync_comments": sync_comments
|
||||
}
|
||||
}
|
||||
status, headers, response_data = json_response(data)
|
||||
start_response(status, headers)
|
||||
return [response_data.encode('utf-8')]
|
||||
|
||||
except Exception as e:
|
||||
print("Issue同步失败: {}".format(str(e)))
|
||||
data = {
|
||||
"success": False,
|
||||
"message": "Issue同步失败: {}".format(str(e)),
|
||||
"timestamp": time.strftime('%Y-%m-%d %H:%M:%S')
|
||||
}
|
||||
status, headers, response_data = json_response(data)
|
||||
start_response(status, headers)
|
||||
return [response_data.encode('utf-8')]
|
||||
|
||||
# 404 Not Found
|
||||
data = {
|
||||
"error": "Not Found",
|
||||
"message": "请求的路径不存在: {}".format(path),
|
||||
"available_endpoints": ["/", "/status", "/sync"]
|
||||
}
|
||||
status, headers, response_data = json_response(data, '404 Not Found')
|
||||
start_response(status, headers)
|
||||
return [response_data.encode('utf-8')]
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("🎯 启动简化版Issue同步服务...")
|
||||
print("📋 服务信息:")
|
||||
print(" - 兼容Python 2.7+")
|
||||
print(" - 监听地址: 0.0.0.0:8001")
|
||||
print(" - 服务状态: http://localhost:8001/status")
|
||||
print(" - 同步接口: http://localhost:8001/sync")
|
||||
print("=" * 50)
|
||||
|
||||
# 创建WSGI服务器
|
||||
httpd = make_server('0.0.0.0', 8001, application)
|
||||
print("✅ 服务器启动成功,监听端口 8001")
|
||||
print("按 Ctrl+C 停止服务")
|
||||
|
||||
try:
|
||||
httpd.serve_forever()
|
||||
except KeyboardInterrupt:
|
||||
print("\n🛑 服务已停止")
|
||||
httpd.shutdown()
|
||||
Loading…
Reference in New Issue