Spaces:
Runtime error
Runtime error
File size: 10,385 Bytes
26e822e |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 |
import gradio as gr
import os
from pathlib import Path
from datetime import datetime
import matplotlib.pyplot as plt
import logging
logger = logging.getLogger("jira_assistant_interface")
def launch_interface(app):
"""
Запуск інтерфейсу користувача Gradio
Args:
app: Екземпляр JiraAssistantApp
"""
# Функція для обробки завантаження та аналізу CSV
def analyze_csv(file_obj, inactive_days, include_ai):
if file_obj is None:
return "Помилка: файл не вибрано", None, None, None, None
try:
logger.info(f"Отримано файл: {file_obj.name}, тип: {type(file_obj)}")
# Створення тимчасового файлу
temp_file_path = os.path.join("temp", f"temp_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv")
# У Gradio 5.19.0 об'єкт файлу має різну структуру
# file_obj може бути шляхом до файлу або містити атрибут 'name'
if hasattr(file_obj, 'name'):
source_path = file_obj.name
# Копіювання файлу
import shutil
shutil.copy2(source_path, temp_file_path)
else:
# Якщо це не шлях до файлу, ймовірно це вже самі дані
with open(temp_file_path, "w", encoding="utf-8") as f:
f.write(str(file_obj))
# Аналіз даних
api_key = os.getenv("OPENAI_API_KEY") if include_ai else None
result = app.analyze_csv_file(
temp_file_path,
inactive_days=inactive_days,
include_ai=include_ai,
api_key=api_key
)
# Видалення тимчасового файлу
try:
os.remove(temp_file_path)
except:
pass
if result.get("error"):
return result.get("error"), None, None, None, None
return (
result.get("report", ""),
result.get("visualizations", {}).get("status"),
result.get("visualizations", {}).get("priority"),
result.get("visualizations", {}).get("created_timeline"),
result.get("ai_analysis", "AI аналіз буде доступний у наступних версіях додатку.")
)
except Exception as e:
import traceback
error_msg = f"Помилка аналізу: {str(e)}\n\n{traceback.format_exc()}"
logger.error(error_msg)
return error_msg, None, None, None, None
# Функція для збереження звіту
def save_report_handler(report_text, format_type, include_visualizations):
if not report_text:
return "Помилка: спочатку виконайте аналіз даних"
return app.save_report(
format_type=format_type,
include_visualizations=include_visualizations
)
# Функція для тестування підключення до Jira
def test_jira_connection_handler(url, username, api_token):
if not url or not username or not api_token:
return "Помилка: необхідно заповнити всі поля (URL, користувач, API токен)"
success = app.test_jira_connection(url, username, api_token)
if success:
return "✅ Успішне підключення до Jira API"
else:
return "❌ Помилка підключення до Jira. Перевірте введені дані."
# Створення інтерфейсу Gradio
with gr.Blocks(title="Jira AI Assistant") as interface:
gr.Markdown("# 🔍 Jira AI Assistant")
with gr.Tabs():
with gr.Tab("CSV Аналіз"):
with gr.Row():
with gr.Column(scale=1):
file_input = gr.File(label="Завантажити CSV файл Jira")
inactive_days = gr.Slider(minimum=1, maximum=90, value=14, step=1,
label="Кількість днів для визначення неактивних тікетів")
include_ai = gr.Checkbox(label="Включити AI аналіз", value=False)
analyze_btn = gr.Button("Аналізувати", variant="primary")
with gr.Accordion("Збереження звіту", open=False):
format_type = gr.Dropdown(
choices=["markdown", "html", "pdf"],
value="markdown",
label="Формат звіту"
)
include_visualizations = gr.Checkbox(
label="Включити візуалізації",
value=True
)
save_btn = gr.Button("Зберегти звіт")
save_output = gr.Textbox(label="Статус збереження")
with gr.Column(scale=2):
with gr.Tabs():
with gr.Tab("Звіт"):
report_output = gr.Markdown()
with gr.Tab("Візуалізації"):
with gr.Row():
status_plot = gr.Plot(label="Статуси тікетів")
priority_plot = gr.Plot(label="Пріоритети тікетів")
timeline_plot = gr.Plot(label="Часова шкала")
with gr.Tab("AI Аналіз"):
ai_output = gr.Markdown()
# Встановлюємо обробники подій
analyze_btn.click(
analyze_csv,
inputs=[file_input, inactive_days, include_ai],
outputs=[report_output, status_plot, priority_plot, timeline_plot, ai_output]
)
save_btn.click(
save_report_handler,
inputs=[report_output, format_type, include_visualizations],
outputs=[save_output]
)
with gr.Tab("Jira API"):
gr.Markdown("## Підключення до Jira API")
with gr.Row():
jira_url = gr.Textbox(
label="Jira URL",
placeholder="https://your-company.atlassian.net"
)
jira_username = gr.Textbox(
label="Ім'я користувача Jira",
placeholder="[email protected]"
)
jira_api_token = gr.Textbox(
label="Jira API Token",
type="password"
)
test_connection_btn = gr.Button("Тестувати з'єднання")
connection_status = gr.Textbox(label="Статус підключення")
test_connection_btn.click(
test_jira_connection_handler,
inputs=[jira_url, jira_username, jira_api_token],
outputs=[connection_status]
)
gr.Markdown("## ⚠️ Ця функція буде доступна у наступних версіях")
with gr.Tab("AI Асистенти"):
gr.Markdown("## AI Асистенти для Jira")
gr.Markdown("⚠️ Ця функція буде доступна у наступних версіях")
with gr.Accordion("Зразок інтерфейсу"):
question = gr.Textbox(
label="Запитання",
placeholder="Наприклад: Які тікети мають найвищий пріоритет?",
lines=2
)
answer = gr.Markdown(label="Відповідь")
with gr.Tab("Інтеграції"):
gr.Markdown("## Інтеграції з зовнішніми системами")
gr.Markdown("⚠️ Ця функція буде доступна у наступних версіях")
with gr.Accordion("Slack інтеграція"):
slack_channel = gr.Textbox(
label="Slack канал",
placeholder="#project-updates"
)
slack_message = gr.Textbox(
label="Повідомлення",
placeholder="Тижневий звіт по проекту",
lines=3
)
slack_send_btn = gr.Button("Надіслати у Slack", interactive=False)
# Запуск інтерфейсу
interface.launch()
# Можливість запустити інтерфейс самостійно (для тестування)
if __name__ == "__main__":
import sys
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from app import JiraAssistantApp
app_instance = JiraAssistantApp()
launch_interface(app_instance) |