Files
Krow-workspace/pages/mailer.py
2026-04-07 12:31:22 +05:30

119 lines
4.6 KiB
Python

import streamlit as st
import pandas as pd
from datetime import date, datetime
from zoneinfo import ZoneInfo
from app_core.services.mailer_service import MailerService
def render_page():
if st.session_state.get("auth_user") is None:
st.warning("Please login to continue.")
st.stop()
st.markdown("## Mailer")
st.caption("Automated daily email sending logs and status.")
service = MailerService()
ist = ZoneInfo("Asia/Kolkata")
st.markdown("### Scheduler Status")
# Check if scheduler container is running by checking if daily report was sent today
today_logs = [log for log in service.recent_logs(limit=1000) if log.get('date_for') == str(date.today())]
daily_report_sent_today = any('Daily Report' in str(log.get('subject', '')) for log in today_logs)
if daily_report_sent_today:
st.success("Scheduler is running - Daily report already sent today")
else:
# Check if it's past 8 PM IST today
now_ist = datetime.now(ist)
eight_pm_today = now_ist.replace(hour=20, minute=0, second=0, microsecond=0)
if now_ist >= eight_pm_today:
st.warning("Scheduler is running - Waiting for next scheduled run (8:00 PM IST daily)")
else:
next_run_ist = eight_pm_today
st.success(f"Scheduler is running - Next report will be sent at {next_run_ist.strftime('%B %d, %Y at %I:%M %p IST')}")
st.markdown("---")
# Show system status
st.markdown("### System Status")
col1, col2, col3 = st.columns(3)
with col1:
st.metric("Total Emails Sent", len([log for log in service.recent_logs(limit=1000) if log.get('status') == 'sent']))
with col2:
failed_count = len([log for log in service.recent_logs(limit=1000) if log.get('status') == 'failed'])
st.metric("Failed Sends", failed_count, delta=f"-{failed_count}" if failed_count > 0 else None)
with col3:
today_logs = [log for log in service.recent_logs(limit=1000) if log.get('date_for') == str(date.today())]
st.metric("Today's Sends", len(today_logs))
st.markdown("---")
# Manual trigger section
st.markdown("### Manual Controls")
mcol1, mcol2, mcol3 = st.columns([2, 2, 3])
with mcol1:
target_date = st.date_input("Report Date", value=date.today())
with mcol2:
st.write("") # Spacer
force_resend = st.checkbox("Force Resend", value=True, help="Send the report even if it was already sent for this date.")
with mcol3:
st.write("") # Spacer
if st.button("Send Report Now", type="primary", use_container_width=True):
with st.spinner(f"Sending report for {target_date}..."):
try:
from app_core.services.daily_report import main as run_daily_report
# Pass the selected date and force flag
result = run_daily_report(for_date=str(target_date), force=force_resend)
if result == 0:
st.success(f"Report for {target_date} sent successfully!")
st.rerun()
else:
st.error(f"Failed to send report (exit code: {result})")
except Exception as e:
st.error(f"Error: {str(e)}")
st.caption("Select a date to manually trigger or re-trigger the daily report email. This is useful for reconciliations.")
st.markdown("---")
# Show email logs table
st.markdown("### Email Logs")
logs = service.recent_logs(limit=100)
if not logs:
st.info("No email logs yet. Automated emails will appear here once sent.")
else:
df_logs = pd.DataFrame(logs)
col_map = {
"id": "ID",
"sent_at": "Sent At",
"recipients": "Recipients",
"subject": "Subject",
"status": "Status",
"error": "Error",
"date_for": "Report Date",
}
df_logs = df_logs[["id", "sent_at", "date_for", "recipients", "subject", "status", "error"]]
df_logs = df_logs.rename(columns=col_map)
# Add status styling
def style_status(val):
if val == 'sent':
return 'background-color: #D1FAE5; color: #065F46; font-weight: 600;'
elif val == 'failed':
return 'background-color: #FEE2E2; color: #991B1B; font-weight: 600;'
return ''
styled_logs = df_logs.style.map(style_status, subset=['Status'])
st.dataframe(styled_logs, use_container_width=True, height=400)
# trigger reload