Files
new_test/app.py
2026-09-19 09:50:20 +00:00

149 lines
5.3 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import re
import os
import sys
import logging
import requests
from flask import Flask, request, jsonify
# Настройка логирования
logging.basicConfig(level=logging.INFO, format='%(message)s', handlers=[logging.StreamHandler(sys.stdout)])
logger = logging.getLogger(__name__)
app = Flask(__name__)
# Конфигурация
GITEA_URL = os.getenv('GITEA_URL', 'https://gitea-copy.teamlead.online')
GITEA_TOKEN = os.getenv('GITEA_TOKEN', '68dbda863bb4c51cb3ef1f8c4e8a69f7221240f5')
# Поиск задач вида ABC-123
TASK_PATTERN = re.compile(r'([A-Z]+-\d+)', re.IGNORECASE)
def find_tasks(text):
"""Находит ключи задач в тексте"""
return set(TASK_PATTERN.findall(text or ''))
def get_compare(owner, repo, base, head):
"""Запрашивает сравнение двух коммитов через API"""
url = f"{GITEA_URL}/api/v1/repos/{owner}/{repo}/compare/{base}...{head}"
headers = {'Authorization': f'token {GITEA_TOKEN}'} if GITEA_TOKEN else {}
try:
resp = requests.get(url, headers=headers)
resp.raise_for_status()
data = resp.json()
logger.info(f"[API] Found {data.get('total_commits', 0)} commits")
return data.get('commits', [])
except Exception as e:
logger.info(f"[API] Error: {e}")
return None
@app.route('/webhook', methods=['POST'])
def webhook():
event = request.headers.get('X-Gitea-Event')
logger.info(f"\n{'='*70}\n[WEBHOOK] Event: {event}")
if event not in ['push', 'delete']:
return jsonify({'status': 'ignored'}), 200
data = request.get_json()
if not data:
return jsonify({'error': 'No data'}), 400
ref = data.get('ref', '')
logger.info(f"[WEBHOOK] Ref: {ref}")
# Удаление ветки
if event == 'delete':
branch = ref.replace('refs/heads/', '')
logger.info(f"[BRANCH DELETED] {branch}")
tasks = find_tasks(branch)
if tasks:
logger.info(f" [TASKS IN DELETED BRANCH] {', '.join(tasks)}")
return jsonify({'status': 'deleted'}), 200
# Только ветки
if not ref.startswith('refs/heads/'):
return jsonify({'status': 'ignored'}), 200
branch = ref.replace('refs/heads/', '')
before, after = data.get('before'), data.get('after')
repo = data.get('repository', {})
owner = repo.get('owner', {}).get('username')
repo_name = repo.get('name')
logger.info(f"[PUSH] {owner}/{repo_name}:{branch}")
logger.info(f" before: {before[:8]}, after: {after[:8]}")
# Создание ветки
if before == '0'*40:
logger.info(f"[BRANCH CREATED] {branch}")
tasks = find_tasks(branch)
if tasks:
logger.info(f" [TASKS IN BRANCH] {', '.join(tasks)}")
process_commits(data.get('commits', []), branch)
return jsonify({'status': 'created'}), 200
# Удаление ветки (через push с after=000)
if after == '0'*40:
logger.info(f"[BRANCH DELETED] {branch}")
return jsonify({'status': 'deleted'}), 200
# Обычный push - ищем новые и удаленные коммиты
logger.info("-"*70)
# Новые коммиты
new_commits = get_compare(owner, repo_name, before, after)
if new_commits:
logger.info(f"[NEW] {len(new_commits)} commits:")
for c in new_commits[:10]:
sha = c.get('sha', '')[:8]
msg = c.get('commit', {}).get('message', '')[:50]
logger.info(f" + {sha}: {msg}")
# Удаленные коммиты
removed_commits = get_compare(owner, repo_name, after, before)
if removed_commits:
logger.info(f"[REMOVED] {len(removed_commits)} commits:")
for c in removed_commits[:10]:
sha = c.get('sha', '')[:8]
msg = c.get('commit', {}).get('message', '')[:50]
tasks = find_tasks(msg)
task_info = f" [TASKS: {', '.join(tasks)}]" if tasks else ""
logger.info(f" - {sha}: {msg}{task_info}")
return jsonify({'status': 'ok'}), 200
def process_commits(commits, branch):
"""Обрабатывает коммиты и ищет задачи"""
if not commits:
return
logger.info(f"\n[COMMITS] {len(commits)} commits:")
all_tasks = find_tasks(branch)
for i, c in enumerate(commits, 1):
sha = c.get('id', '')[:8]
msg = c.get('message', '')
tasks = find_tasks(msg)
all_tasks.update(tasks)
logger.info(f" {i}. {sha}: {msg[:60]}" + (f" [TASKS: {', '.join(tasks)}]" if tasks else ""))
if all_tasks:
logger.info(f"\n[SUMMARY] Found tasks: {', '.join(sorted(all_tasks))}")
@app.route('/', methods=['GET'])
def index():
return f"""
<h1>Gitea Webhook Handler</h1>
<p>Webhook URL: <code>/webhook</code></p>
<p>Gitea API: <code>{GITEA_URL}</code></p>
<p>Token: {'[SET]' if GITEA_TOKEN else '[NOT SET]'}</p>
"""
if __name__ == '__main__':
logger.info(f"\n{'='*70}\nGITEA WEBHOOK HANDLER\n{'='*70}")
logger.info(f"Server: http://0.0.0.0:5000")
logger.info(f"Webhook: https://gitea-copy.teamlead.online:5000/webhook")
logger.info(f"Gitea API: {GITEA_URL}")
logger.info(f"{'='*70}\n")
app.run(host='0.0.0.0', port=5000, debug=False)