129 lines
4.8 KiB
Python
129 lines
4.8 KiB
Python
#!/usr/bin/env python3
|
||
"""Получение списка заявок из ServiceDesk Plus. Экспорт: Группа, Описание, Назначено, Категория в JSONL."""
|
||
|
||
import requests
|
||
import json
|
||
import urllib3
|
||
from datetime import datetime
|
||
from html import unescape
|
||
import re
|
||
import sys
|
||
import os
|
||
|
||
# Отключаем ворнинги для чистой работы консоли
|
||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||
|
||
# --- ИМПОРТ КОНФИГУРАЦИИ (ВСЕ ПЕРЕМЕННЫЕ ИДУТ ОТСЮДА) ---
|
||
# config.py лежит в /opt/GigaAM/config/, а скрипт в /opt/GigaAM/sd/
|
||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||
|
||
try:
|
||
from config import *
|
||
print("LOG: ✅ Config импортирован из config.py")
|
||
except Exception as e:
|
||
print(f"LOG: ⚠️ Не удалось импортировать config: {e}", file=sys.stderr)
|
||
|
||
# Проверяем что SERVER_URL определён, если нет — используем дефолт
|
||
if 'SERVER_URL' not in globals():
|
||
SERVER_URL = os.environ.get("SD_SERVER_URL", "https://servicedesk.sibcem.ru:8080")
|
||
print(f"LOG: ⚠️ SERVER_URL не найден в config, используем: {SERVER_URL}")
|
||
|
||
if 'API_KEY' not in globals():
|
||
API_KEY = os.environ.get("SD_API_KEY", "")
|
||
print("LOG: ⚠️ API_KEY не найден в config, используется пустой", file=sys.stderr)
|
||
|
||
print(f"LOG: 🔑 Подключение к {SERVER_URL}")
|
||
|
||
def get_ts(req):
|
||
ct = req.get("created_time", {})
|
||
if isinstance(ct, dict):
|
||
v = ct.get("value", "0")
|
||
return int(v) if v else 0
|
||
return 0
|
||
|
||
def clean_html(text):
|
||
if not text:
|
||
return ""
|
||
text = re.sub(r'<[^>]+>', '', text)
|
||
text = unescape(text)
|
||
return text.strip()
|
||
|
||
def get_name(obj):
|
||
"""Извлечь имя из объекта группы/техника/категории."""
|
||
if not obj:
|
||
return ""
|
||
if isinstance(obj, dict):
|
||
return obj.get("name", "") or obj.get("display_value", "")
|
||
return str(obj)
|
||
|
||
def get_ticket_detail(ticket_id):
|
||
"""Получить детальную информацию по заявке."""
|
||
try:
|
||
url = f"{SERVER_URL}/api/v3/requests/{ticket_id}"
|
||
headers = {"authtoken": API_KEY, "Accept": "application/vnd.manageengine.sdp.v3+json"}
|
||
resp = requests.get(url, headers=headers, verify=False, timeout=15.0)
|
||
resp.raise_for_status()
|
||
data = resp.json()
|
||
return data.get("request", data)
|
||
except Exception as e:
|
||
return {}
|
||
|
||
def list_tickets(from_date="2026-07-20"):
|
||
url = f"{SERVER_URL}/api/v3/requests"
|
||
headers = {"authtoken": API_KEY, "Accept": "application/vnd.manageengine.sdp.v3+json"}
|
||
|
||
# Вычисляем timestamp с указанной даты
|
||
date_obj = datetime.strptime(from_date, "%Y-%m-%d")
|
||
from_date_ms = int(date_obj.replace(tzinfo=__import__('datetime').timezone.utc).timestamp() * 1000)
|
||
|
||
print(f"LOG: 📥 Загрузка заявок с {from_date}...")
|
||
resp = requests.get(url, headers=headers, verify=False, timeout=30.0)
|
||
resp.raise_for_status()
|
||
data = resp.json()
|
||
all_reqs = data.get("requests", [])
|
||
|
||
from_date_reqs = [r for r in all_reqs if get_ts(r) >= from_date_ms]
|
||
print(f"LOG: 📋 Найдено заявок с {from_date}: {len(from_date_reqs)}")
|
||
|
||
# Получаем детали для каждой заявки
|
||
rows = []
|
||
for i, req in enumerate(from_date_reqs):
|
||
if (i + 1) % 10 == 0:
|
||
print(f" Обработано {i + 1}/{len(from_date_reqs)}...")
|
||
|
||
req_id = req.get("request_id", req.get("id", "?"))
|
||
detail = get_ticket_detail(req_id)
|
||
|
||
# Группа — из списка
|
||
group = req.get("group", {})
|
||
group_name = get_name(group)
|
||
|
||
# Описание — из детального запроса
|
||
desc = detail.get("description", "")
|
||
desc_clean = clean_html(desc)
|
||
|
||
# Назначено (специалист) — из детального запроса
|
||
tech = detail.get("technician", {})
|
||
assignee = get_name(tech)
|
||
|
||
# Категория — из детального запроса
|
||
cat = detail.get("category", {})
|
||
category = get_name(cat)
|
||
|
||
rows.append({
|
||
"group": group_name,
|
||
"description": desc_clean,
|
||
"assignee": assignee,
|
||
"category": category
|
||
})
|
||
|
||
# Выводим JSONL
|
||
for row in rows:
|
||
print(json.dumps(row, ensure_ascii=False))
|
||
|
||
print(f"LOG: ✅ Выведено {len(rows)} заявок", file=sys.stderr)
|
||
|
||
if __name__ == "__main__":
|
||
from_date = sys.argv[1] if len(sys.argv) > 1 else "2026-07-20"
|
||
list_tickets(from_date)
|