#!/usr/bin/env python3 """Получение списка заявок из ServiceDesk Plus. Экспорт: Группа, Описание, Назначено, Категория в JSONL/JSON/CSV.""" import requests import json import csv import urllib3 from datetime import datetime from html import unescape import re import sys import os # Отключаем ворнинги для чистой работы консоли urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) # --- ПОЛУЧЕНИЕ API_KEY ИЗ PASSWORK --- SERVER_URL = "https://servicedesk.sibcem.ru:8080" API_KEY = "" # 1. Пробуем passwork напрямую try: sys.path.insert(0, "/opt/passwork") from passwork import get_passwork_secrets passwork_pool = get_passwork_secrets(required_cards=["sdesktoken"]) card = passwork_pool.get("sdesktoken") if card: API_KEY = card.get("password", "").strip() print("LOG: API_KEY получен из passwork (sdesktoken)") else: print("LOG: Карточка sdesktoken не найдена в passwork", file=sys.stderr) except Exception as e: print(f"LOG: Passwork ошибка: {e}", file=sys.stderr) # 2. Пробуем config.py if not API_KEY: try: sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) import config as cfg API_KEY = getattr(cfg, 'API_KEY', "") if API_KEY: print("LOG: API_KEY получен из config.py") except Exception: pass # 3. Пробуем env var if not API_KEY: API_KEY = os.environ.get("SD_API_KEY", "") if API_KEY: print("LOG: API_KEY получен из SD_API_KEY") if not API_KEY: print("LOG: ОШИБКА: API_KEY не найден нигде! Нужен passwork или SD_API_KEY", file=sys.stderr) sys.exit(1) 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", json_file=None, csv_file=None): url = f"{SERVER_URL}/api/v3/requests" headers = {"authtoken": API_KEY, "Accept": "application/vnd.manageengine.sdp.v3+json"} 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 }) # Определяем путь для файлов по умолчанию (та же директория что и скрипт) script_dir = os.path.dirname(os.path.abspath(__file__)) timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") if json_file is None: json_file = os.path.join(script_dir, f"tickets_{timestamp}.json") if csv_file is None: csv_file = os.path.join(script_dir, f"tickets_{timestamp}.csv") # Сохраняем JSON with open(json_file, 'w', encoding='utf-8') as f: json.dump(rows, f, ensure_ascii=False, indent=2) print(f"LOG: JSON сохранён: {json_file}") # Сохраняем CSV with open(csv_file, 'w', encoding='utf-8', newline='') as f: writer = csv.DictWriter(f, fieldnames=["group", "description", "assignee", "category"]) writer.writeheader() writer.writerows(rows) print(f"LOG: CSV сохранён: {csv_file}") # Выводим JSONL в консоль for row in rows: print(json.dumps(row, ensure_ascii=False)) print(f"LOG: Выведено {len(rows)} заявок", file=sys.stderr) if __name__ == "__main__": import argparse parser = argparse.ArgumentParser(description="Выгрузка заявок из ServiceDesk Plus") parser.add_argument("--from", dest="from_date", default="2026-07-20", help="Дата начала (YYYY-MM-DD)") parser.add_argument("--json", dest="json_file", default=None, help="Путь к JSON файлу") parser.add_argument("--csv", dest="csv_file", default=None, help="Путь к CSV файлу") args = parser.parse_args() list_tickets(from_date=args.from_date, json_file=args.json_file, csv_file=args.csv_file)