Spaces:
Sleeping
Sleeping
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(
|