Spaces:
Running
Running
Commit
·
4475e24
1
Parent(s):
cf42361
3.74 fixes display and output
Browse files
app.py
CHANGED
@@ -665,25 +665,53 @@ class ProcessingUI:
|
|
665 |
st.session_state.recent_items = st.session_state.recent_items[:10]
|
666 |
|
667 |
# Create HTML for all recent items
|
668 |
-
items_html = "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
669 |
|
670 |
for item in st.session_state.recent_items:
|
671 |
if item['sentiment'] in ['Positive', 'Negative']: # Only show Positive and Negative items
|
672 |
-
|
673 |
-
if item['
|
674 |
-
item_class += 'negative-item'
|
675 |
-
elif item['sentiment'] == 'Positive':
|
676 |
-
item_class += 'positive-item'
|
677 |
|
678 |
items_html += f"""
|
679 |
-
<div class=
|
680 |
-
<
|
681 |
-
{item['headline']}
|
682 |
-
<
|
683 |
Тональность: {item['sentiment']}
|
684 |
-
{f" |
|
685 |
| {item['time']}
|
686 |
-
</
|
687 |
</div>
|
688 |
"""
|
689 |
|
@@ -1467,93 +1495,110 @@ def create_output_file(df, uploaded_file, llm):
|
|
1467 |
try:
|
1468 |
wb = load_workbook("sample_file.xlsx")
|
1469 |
|
1470 |
-
|
1471 |
ws = wb['Мониторинг']
|
1472 |
row_idx = 4
|
1473 |
-
|
1474 |
-
|
1475 |
-
|
1476 |
-
|
1477 |
-
|
1478 |
-
|
1479 |
-
|
1480 |
-
|
1481 |
-
|
1482 |
-
#
|
1483 |
-
|
1484 |
-
|
1485 |
-
|
1486 |
-
|
1487 |
-
|
1488 |
-
|
1489 |
-
|
1490 |
-
|
|
|
|
|
|
|
|
|
1491 |
entity_impacts = {}
|
1492 |
for entity in df['Объект'].unique():
|
1493 |
-
|
1494 |
-
|
1495 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1496 |
|
1497 |
# Update 'Сводка' sheet
|
1498 |
ws = wb['Сводка']
|
1499 |
for idx, (entity, row) in enumerate(entity_stats.iterrows(), start=4):
|
1500 |
-
ws.cell(row=idx, column=5, value=entity)
|
1501 |
-
ws.cell(row=idx, column=6, value=row['Всего'])
|
1502 |
-
ws.cell(row=idx, column=7, value=row['Негативные'])
|
1503 |
-
ws.cell(row=idx, column=8, value=row['Позитивные'])
|
1504 |
-
ws.cell(row=idx, column=9, value=entity_impacts
|
1505 |
|
1506 |
-
# Update 'Значимые' sheet
|
1507 |
ws = wb['Значимые']
|
1508 |
row_idx = 3
|
1509 |
-
|
1510 |
-
|
1511 |
-
|
1512 |
-
|
1513 |
-
|
1514 |
-
|
1515 |
-
|
1516 |
-
|
1517 |
-
|
1518 |
-
|
1519 |
-
|
1520 |
-
|
|
|
|
|
|
|
|
|
1521 |
ws = wb['Публикации']
|
1522 |
-
for r_idx, row in enumerate(dataframe_to_rows(
|
1523 |
for c_idx, value in enumerate(row, start=1):
|
1524 |
ws.cell(row=r_idx, column=c_idx, value=value)
|
1525 |
-
|
1526 |
-
|
1527 |
-
# Update 'Анализ' sheet with modified translation handling
|
1528 |
ws = wb['Анализ']
|
1529 |
row_idx = 4
|
1530 |
-
|
|
|
1531 |
ws.cell(row=row_idx, column=5, value=row['Объект'])
|
1532 |
ws.cell(row=row_idx, column=6, value=row['Заголовок'])
|
1533 |
ws.cell(row=row_idx, column=7, value="Риск убытка")
|
1534 |
|
1535 |
-
|
1536 |
-
if pd.notna(
|
1537 |
try:
|
1538 |
grlm = init_langchain_llm("Groq (llama-3.1-70b)")
|
1539 |
-
translated_reasoning = translate_reasoning_to_russian(grlm,
|
1540 |
ws.cell(row=row_idx, column=8, value=translated_reasoning)
|
1541 |
except Exception as e:
|
1542 |
-
|
1543 |
-
ws.cell(row=row_idx, column=8, value=row['Reasoning']) # Use original text as fallback
|
1544 |
|
1545 |
ws.cell(row=row_idx, column=9, value=row['Выдержки из текста'])
|
1546 |
row_idx += 1
|
1547 |
|
1548 |
# Update 'Тех.приложение' sheet
|
1549 |
-
|
|
|
|
|
1550 |
if 'Тех.приложение' not in wb.sheetnames:
|
1551 |
wb.create_sheet('Тех.приложение')
|
1552 |
ws = wb['Тех.приложение']
|
|
|
1553 |
for r_idx, row in enumerate(dataframe_to_rows(tech_df, index=False, header=True), start=1):
|
1554 |
for c_idx, value in enumerate(row, start=1):
|
1555 |
ws.cell(row=r_idx, column=c_idx, value=value)
|
1556 |
-
|
1557 |
|
1558 |
output = io.BytesIO()
|
1559 |
wb.save(output)
|
@@ -1561,14 +1606,14 @@ def create_output_file(df, uploaded_file, llm):
|
|
1561 |
return output
|
1562 |
|
1563 |
except Exception as e:
|
1564 |
-
st.
|
1565 |
return None
|
1566 |
|
1567 |
def main():
|
1568 |
st.set_page_config(layout="wide")
|
1569 |
|
1570 |
with st.sidebar:
|
1571 |
-
st.title("::: AI-анализ мониторинга новостей (v.3.
|
1572 |
st.subheader("по материалам СКАН-ИНТЕРФАКС")
|
1573 |
|
1574 |
model_choice = st.radio(
|
|
|
665 |
st.session_state.recent_items = st.session_state.recent_items[:10]
|
666 |
|
667 |
# Create HTML for all recent items
|
668 |
+
items_html = f"""
|
669 |
+
<style>
|
670 |
+
.items-container {{
|
671 |
+
max-height: 400px;
|
672 |
+
overflow-y: auto;
|
673 |
+
}}
|
674 |
+
.news-item {{
|
675 |
+
padding: 10px;
|
676 |
+
margin: 10px 0;
|
677 |
+
border-radius: 4px;
|
678 |
+
background-color: #f8f9fa;
|
679 |
+
}}
|
680 |
+
.news-item.negative {{
|
681 |
+
border-left: 4px solid #FF6B6B;
|
682 |
+
}}
|
683 |
+
.news-item.positive {{
|
684 |
+
border-left: 4px solid #4ECDC4;
|
685 |
+
}}
|
686 |
+
.news-item .entity {{
|
687 |
+
font-weight: bold;
|
688 |
+
color: #333;
|
689 |
+
}}
|
690 |
+
.news-item .headline {{
|
691 |
+
margin: 5px 0;
|
692 |
+
}}
|
693 |
+
.news-item .meta {{
|
694 |
+
font-size: 0.9em;
|
695 |
+
color: #666;
|
696 |
+
}}
|
697 |
+
</style>
|
698 |
+
<div class="items-container">
|
699 |
+
"""
|
700 |
|
701 |
for item in st.session_state.recent_items:
|
702 |
if item['sentiment'] in ['Positive', 'Negative']: # Only show Positive and Negative items
|
703 |
+
sentiment_class = 'negative' if item['sentiment'] == 'Negative' else 'positive'
|
704 |
+
event_info = f"Событие: {item['event_type']}" if item['event_type'] != 'Нет' else ""
|
|
|
|
|
|
|
705 |
|
706 |
items_html += f"""
|
707 |
+
<div class="news-item {sentiment_class}">
|
708 |
+
<div class="entity">{item['entity']}</div>
|
709 |
+
<div class="headline">{item['headline']}</div>
|
710 |
+
<div class="meta">
|
711 |
Тональность: {item['sentiment']}
|
712 |
+
{f" | {event_info}" if event_info else ""}
|
713 |
| {item['time']}
|
714 |
+
</div>
|
715 |
</div>
|
716 |
"""
|
717 |
|
|
|
1495 |
try:
|
1496 |
wb = load_workbook("sample_file.xlsx")
|
1497 |
|
1498 |
+
# Update 'Мониторинг' sheet with events
|
1499 |
ws = wb['Мониторинг']
|
1500 |
row_idx = 4
|
1501 |
+
events_df = df[df['Event_Type'] != 'Нет'].copy()
|
1502 |
+
for _, row in events_df.iterrows():
|
1503 |
+
ws.cell(row=row_idx, column=5, value=row['Объект'])
|
1504 |
+
ws.cell(row=row_idx, column=6, value=row['Заголовок'])
|
1505 |
+
ws.cell(row=row_idx, column=7, value=row['Event_Type'])
|
1506 |
+
ws.cell(row=row_idx, column=8, value=row['Event_Summary'])
|
1507 |
+
ws.cell(row=row_idx, column=9, value=row['Выдержки из текста'])
|
1508 |
+
row_idx += 1
|
1509 |
+
|
1510 |
+
# Calculate statistics safely
|
1511 |
+
try:
|
1512 |
+
entity_stats = pd.DataFrame({
|
1513 |
+
'Объект': df['Объект'].unique(),
|
1514 |
+
'Всего': df.groupby('Объект').size(),
|
1515 |
+
'Негативные': df[df['Sentiment'] == 'Negative'].groupby('Объект').size().fillna(0).astype(int),
|
1516 |
+
'Позитивные': df[df['Sentiment'] == 'Positive'].groupby('О��ъект').size().fillna(0).astype(int)
|
1517 |
+
}).sort_values('Негативные', ascending=False)
|
1518 |
+
except Exception as e:
|
1519 |
+
st.warning(f"Error calculating entity stats: {str(e)}")
|
1520 |
+
entity_stats = pd.DataFrame(columns=['Объект', 'Всего', 'Негативные', 'Позитивные'])
|
1521 |
+
|
1522 |
+
# Calculate impacts safely
|
1523 |
entity_impacts = {}
|
1524 |
for entity in df['Объект'].unique():
|
1525 |
+
try:
|
1526 |
+
entity_df = df[df['Объект'] == entity]
|
1527 |
+
negative_df = entity_df[entity_df['Sentiment'] == 'Negative']
|
1528 |
+
if len(negative_df) > 0 and 'Impact' in negative_df.columns:
|
1529 |
+
impacts = negative_df['Impact'].dropna()
|
1530 |
+
entity_impacts[entity] = impacts.iloc[0] if len(impacts) > 0 else 'Неопределенный эффект'
|
1531 |
+
else:
|
1532 |
+
entity_impacts[entity] = 'Неопределенный эффект'
|
1533 |
+
except Exception as e:
|
1534 |
+
st.warning(f"Error calculating impact for {entity}: {str(e)}")
|
1535 |
+
entity_impacts[entity] = 'Неопределенный эффект'
|
1536 |
|
1537 |
# Update 'Сводка' sheet
|
1538 |
ws = wb['Сводка']
|
1539 |
for idx, (entity, row) in enumerate(entity_stats.iterrows(), start=4):
|
1540 |
+
ws.cell(row=idx, column=5, value=entity)
|
1541 |
+
ws.cell(row=idx, column=6, value=row['Всего'])
|
1542 |
+
ws.cell(row=idx, column=7, value=row['Негативные'])
|
1543 |
+
ws.cell(row=idx, column=8, value=row['Позитивные'])
|
1544 |
+
ws.cell(row=idx, column=9, value=entity_impacts.get(entity, 'Неопределенный эффект'))
|
1545 |
|
1546 |
+
# Update 'Значимые' sheet with both negative and positive
|
1547 |
ws = wb['Значимые']
|
1548 |
row_idx = 3
|
1549 |
+
sentiment_df = df[df['Sentiment'].isin(['Negative', 'Positive'])].copy()
|
1550 |
+
for _, row in sentiment_df.iterrows():
|
1551 |
+
cols = ['Объект', 'Заголовок', 'Sentiment', 'Impact', 'Выдержки из текста']
|
1552 |
+
for col in cols:
|
1553 |
+
if col not in row:
|
1554 |
+
row[col] = '' # Handle missing columns
|
1555 |
+
|
1556 |
+
ws.cell(row=row_idx, column=3, value=row['Объект'])
|
1557 |
+
ws.cell(row=row_idx, column=4, value='релевантно')
|
1558 |
+
ws.cell(row=row_idx, column=5, value=row['Sentiment'])
|
1559 |
+
ws.cell(row=row_idx, column=6, value=row.get('Impact', ''))
|
1560 |
+
ws.cell(row=row_idx, column=7, value=row['Заголовок'])
|
1561 |
+
ws.cell(row=row_idx, column=8, value=row['Выдержки из текста'])
|
1562 |
+
row_idx += 1
|
1563 |
+
|
1564 |
+
# Copy processed rows to 'Публикации' sheet
|
1565 |
ws = wb['Публикации']
|
1566 |
+
for r_idx, row in enumerate(dataframe_to_rows(df, index=False, header=True), start=1):
|
1567 |
for c_idx, value in enumerate(row, start=1):
|
1568 |
ws.cell(row=r_idx, column=c_idx, value=value)
|
1569 |
+
|
1570 |
+
# Update 'Анализ' sheet safely
|
|
|
1571 |
ws = wb['Анализ']
|
1572 |
row_idx = 4
|
1573 |
+
negative_df = df[df['Sentiment'] == 'Negative'].copy()
|
1574 |
+
for _, row in negative_df.iterrows():
|
1575 |
ws.cell(row=row_idx, column=5, value=row['Объект'])
|
1576 |
ws.cell(row=row_idx, column=6, value=row['Заголовок'])
|
1577 |
ws.cell(row=row_idx, column=7, value="Риск убытка")
|
1578 |
|
1579 |
+
reasoning = row.get('Reasoning', '')
|
1580 |
+
if reasoning and pd.notna(reasoning):
|
1581 |
try:
|
1582 |
grlm = init_langchain_llm("Groq (llama-3.1-70b)")
|
1583 |
+
translated_reasoning = translate_reasoning_to_russian(grlm, reasoning)
|
1584 |
ws.cell(row=row_idx, column=8, value=translated_reasoning)
|
1585 |
except Exception as e:
|
1586 |
+
ws.cell(row=row_idx, column=8, value=reasoning)
|
|
|
1587 |
|
1588 |
ws.cell(row=row_idx, column=9, value=row['Выдержки из текста'])
|
1589 |
row_idx += 1
|
1590 |
|
1591 |
# Update 'Тех.приложение' sheet
|
1592 |
+
tech_cols = ['Объект', 'Заголовок', 'Выдержки из текста', 'Translated', 'Sentiment', 'Impact', 'Reasoning']
|
1593 |
+
tech_df = df[[col for col in tech_cols if col in df.columns]].copy()
|
1594 |
+
|
1595 |
if 'Тех.приложение' not in wb.sheetnames:
|
1596 |
wb.create_sheet('Тех.приложение')
|
1597 |
ws = wb['Тех.приложение']
|
1598 |
+
|
1599 |
for r_idx, row in enumerate(dataframe_to_rows(tech_df, index=False, header=True), start=1):
|
1600 |
for c_idx, value in enumerate(row, start=1):
|
1601 |
ws.cell(row=r_idx, column=c_idx, value=value)
|
|
|
1602 |
|
1603 |
output = io.BytesIO()
|
1604 |
wb.save(output)
|
|
|
1606 |
return output
|
1607 |
|
1608 |
except Exception as e:
|
1609 |
+
st.error(f"Error creating output file: {str(e)}")
|
1610 |
return None
|
1611 |
|
1612 |
def main():
|
1613 |
st.set_page_config(layout="wide")
|
1614 |
|
1615 |
with st.sidebar:
|
1616 |
+
st.title("::: AI-анализ мониторинга новостей (v.3.74):::")
|
1617 |
st.subheader("по материалам СКАН-ИНТЕРФАКС")
|
1618 |
|
1619 |
model_choice = st.radio(
|