import streamlit as st
import pandas as pd
import sqlite3
import plotly.express as px
from wordcloud import WordCloud
import matplotlib.pyplot as plt
from analyzer import analyze_sentiment, calculate_priority_score, classify_theme, get_lemmas
# Конфигурация страницы
st.set_page_config(page_title="Insta Analytics Search", layout="wide", initial_sidebar_state="collapsed")
# Стили
st.markdown("""
""", unsafe_allow_html=True)
@st.cache_data
def load_data():
try:
conn = sqlite3.connect('instagram_data.db')
c = pd.read_sql("SELECT * FROM comments", conn)
conn.close()
c['comment_date'] = pd.to_datetime(c['comment_date'], errors='coerce')
return c
except:
return pd.DataFrame()
comments_all = load_data()
st.markdown("
Insight Search
", unsafe_allow_html=True)
if 'search_results' not in st.session_state:
st.session_state['search_results'] = pd.DataFrame()
col_spacer1, col_search, col_spacer2 = st.columns([1, 4, 1])
with col_search:
search_query = st.text_input("Поиск", placeholder="Введите URL, слова, никнейм или текст...", label_visibility="collapsed")
mode = st.radio("Режим", ["🔑 По словам", "🔗 По URL поста", "👤 По автору (Нику)", "✍️ Один текст"], label_visibility="collapsed", horizontal=True)
analyze_clicked = st.button("Анализировать", use_container_width=True)
st.divider()
if analyze_clicked:
if not search_query.strip():
st.warning("Пожалуйста, введите запрос!")
else:
term = search_query.strip().lower()
res = pd.DataFrame()
if mode == "🔑 По словам":
keys = [k.strip().lower() for k in search_query.split(',')]
res = comments_all[comments_all['comment_text'].apply(lambda x: any(k in str(x).lower() for k in keys))].copy()
elif mode == "🔗 По URL поста":
res = comments_all[comments_all['post_url'].astype(str).str.contains(term, na=False, case=False)].copy()
elif mode == "👤 По автору (Нику)":
res = comments_all[comments_all['comment_author'].astype(str).str.lower().str.contains(term, na=False)].copy()
elif mode == "✍️ Один текст":
res = pd.DataFrame([{'comment_text': search_query, 'comment_author': 'Вы', 'comment_date': pd.Timestamp.now()}])
if res.empty:
st.error("По вашему запросу ничего не найдено.")
st.session_state['search_results'] = pd.DataFrame()
else:
with st.spinner('ИИ анализирует данные...'):
res['sentiment'] = analyze_sentiment(res['comment_text'].tolist())
res['theme'] = res['comment_text'].apply(classify_theme)
res['priority'] = res.apply(calculate_priority_score, axis=1)
st.session_state['search_results'] = res
# ОТОБРАЖЕНИЕ
if not st.session_state['search_results'].empty:
df_result = st.session_state['search_results']
st.markdown("Фильтр комментариев:
", unsafe_allow_html=True)
sentiment_filter = st.radio("Тональность", ["Все", "🟢 Позитив", "🔴 Негатив", "⚪ Нейтрально"], horizontal=True, label_visibility="collapsed")
df_filtered = df_result.copy()
if sentiment_filter == "🟢 Позитив":
df_filtered = df_filtered[df_filtered['sentiment'] == 'Позитив']
elif sentiment_filter == "🔴 Негатив":
df_filtered = df_filtered[df_filtered['sentiment'] == 'Негатив']
elif sentiment_filter == "⚪ Нейтрально":
df_filtered = df_filtered[df_filtered['sentiment'] == 'Нейтрально']
st.markdown(f"## Результаты ({len(df_filtered)} шт.)")
# Метрики
c1, c2, c3, c4 = st.columns(4)
with c1: st.markdown(f'Всего{len(df_filtered)} шт.
', unsafe_allow_html=True)
with c2:
val = df_filtered["sentiment"].mode()[0] if not df_filtered.empty else "—"
st.markdown(f'Настрой{val}
', unsafe_allow_html=True)
with c3:
val = df_filtered["theme"].mode()[0] if not df_filtered.empty else "—"
st.markdown(f'Тема{val}
', unsafe_allow_html=True)
with c4:
val = df_filtered["priority"].mean() if not df_filtered.empty else 0
st.markdown(f'Приоритет{val:.1f}
', unsafe_allow_html=True)
# Графики
g1, g2 = st.columns(2)
with g1:
fig = px.pie(df_filtered, names='sentiment', color='sentiment', hole=0.3,
color_discrete_map={'Позитив':'#82ca9d', 'Негатив':'#E83E8C', 'Нейтрально':'#8884d8'})
fig.update_layout(paper_bgcolor="rgba(0,0,0,0)", font_color="white")
st.plotly_chart(fig, use_container_width=True)
with g2:
if len(df_filtered) > 0:
txt = " ".join(df_filtered['comment_text'].astype(str))
wc = WordCloud(width=800, height=400, background_color=None, mode="RGBA").generate(txt)
fig_wc, ax = plt.subplots(); ax.imshow(wc); ax.axis("off")
fig_wc.patch.set_alpha(0)
st.pyplot(fig_wc)
# Таблица
st.markdown("### 📋 Детализация комментариев")
df_display = df_filtered.copy()
df_display['comment_date'] = pd.to_datetime(df_display['comment_date']).dt.strftime('%d.%m.%Y %H:%M')
df_display['Профиль'] = df_display['comment_author'].apply(lambda x: f"https://www.instagram.com/{x}/")
df_display = df_display[['priority', 'sentiment', 'theme', 'comment_text', 'comment_author', 'Профиль', 'comment_date']]
df_display.columns = ['Приоритет', 'Тональность', 'Тема', 'Текст', 'Автор', 'Instagram', 'Дата']
st.dataframe(df_display.sort_values(by='Приоритет', ascending=False), use_container_width=True, hide_index=True,
column_config={"Instagram": st.column_config.LinkColumn("Instagram")})
st.download_button("📥 Скачать отчет (CSV)", df_display.to_csv(index=False).encode('utf-8-sig'), "report.csv", "text/csv")
# ИНСАЙТЫ (ИСПРАВЛЕНО)
st.markdown("---")
st.markdown("### 💡 Инсайты разведки")
# Проверяем негатив во ВСЕЙ найденной по запросу выборке (df_result)
neg_data = df_result[df_result['sentiment'] == 'Негатив']
if not neg_data.empty:
count_bad = len(neg_data)
bad_topic = neg_data['theme'].mode()[0]
st.error(f"⚠️ **Внимание:** В результатах поиска обнаружено **{count_bad}** негативных сообщений! Основная проблемная тема: **{bad_topic}**. Требуется анализ рисков.")
else:
st.success("✅ **Положительный инсайт:** В данной выборке не обнаружено негативных проявлений. Аудитория лояльна.")