ujwal55's picture
Update app.py
6c7dfdd verified
import streamlit as st
from pymongo import MongoClient
from pymongo.errors import ConnectionFailure
import datetime
import os
# Page configuration
st.set_page_config(
page_title="GitHub Activity Feed",
page_icon="πŸš€",
layout="wide",
initial_sidebar_state="collapsed"
)
# Custom CSS for beautiful UI
st.markdown("""
<style>
.main {
padding-top: 2rem;
}
.stTitle {
color: #1f2937;
font-size: 3rem !important;
font-weight: 700 !important;
text-align: center;
margin-bottom: 2rem;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.activity-card {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
padding: 1.5rem;
border-radius: 12px;
margin: 1rem 0;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
color: white;
border-left: 4px solid #f59e0b;
}
.activity-text {
font-size: 1.1rem;
font-weight: 500;
margin: 0;
}
.activity-time {
font-size: 0.9rem;
opacity: 0.8;
margin-top: 0.5rem;
}
.stats-container {
display: flex;
justify-content: space-around;
margin: 2rem 0;
}
.stat-card {
background: white;
padding: 1.5rem;
border-radius: 12px;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
text-align: center;
flex: 1;
margin: 0 0.5rem;
border-top: 4px solid #10b981;
}
.stat-number {
font-size: 2rem;
font-weight: 700;
color: #1f2937;
margin: 0;
}
.stat-label {
color: #6b7280;
font-size: 0.9rem;
margin-top: 0.5rem;
}
.no-events {
text-align: center;
padding: 3rem;
color: #6b7280;
font-size: 1.2rem;
background: #f9fafb;
border-radius: 12px;
margin: 2rem 0;
}
.header-subtitle {
text-align: center;
color: #6b7280;
font-size: 1.2rem;
margin-bottom: 3rem;
}
.activity-icon {
font-size: 1.5rem;
margin-right: 0.5rem;
}
.status-indicator {
display: inline-block;
width: 12px;
height: 12px;
border-radius: 50%;
margin-right: 8px;
}
.status-connected {
background-color: #10b981;
animation: pulse 2s infinite;
}
.status-disconnected {
background-color: #ef4444;
}
@keyframes pulse {
0% { opacity: 1; }
50% { opacity: 0.5; }
100% { opacity: 1; }
}
</style>
""", unsafe_allow_html=True)
# App header
st.markdown('<h1 class="stTitle">πŸš€ GitHub Activity Feed</h1>', unsafe_allow_html=True)
st.markdown('<p class="header-subtitle">Real-time monitoring of your GitHub repository activities</p>', unsafe_allow_html=True)
# Database connection
@st.cache_resource
def init_connection():
try:
# Get MongoDB URI from environment variable
mongodb_uri = os.getenv('MONGODB_URI', 'mongodb://localhost:27017/')
client = MongoClient(
mongodb_uri,
serverSelectionTimeoutMS=5000,
connectTimeoutMS=5000
)
# Test the connection
client.admin.command('ping')
return client
except ConnectionFailure as e:
st.error(f"Database connection failed: {e}")
return None
except Exception as e:
st.error(f"Unexpected error: {e}")
return None
# Initialize connection
client = init_connection()
# Connection status indicator
if client:
st.markdown(
'<div style="text-align: center; margin-bottom: 2rem;">'
'<span class="status-indicator status-connected"></span>'
'<span style="color: #10b981; font-weight: 500;">Database Connected</span>'
'</div>',
unsafe_allow_html=True
)
else:
st.markdown(
'<div style="text-align: center; margin-bottom: 2rem;">'
'<span class="status-indicator status-disconnected"></span>'
'<span style="color: #ef4444; font-weight: 500;">Database Disconnected</span>'
'</div>',
unsafe_allow_html=True
)
if client:
db = client["github_webhooks"]
collection = db["events"]
# Manual refresh section
col1, col2, col3 = st.columns([1, 1, 1])
with col2:
if st.button("πŸ”„ Refresh Data", key="refresh_btn", type="primary"):
# Clear cache to force refresh
st.cache_resource.clear()
st.rerun()
# Auto-refresh toggle
col1, col2, col3 = st.columns([1, 1, 1])
with col2:
auto_refresh = st.checkbox("πŸ”„ Auto-refresh (30s)", value=False)
# Fetch events
try:
events = list(collection.find().sort("timestamp", -1).limit(20))
# Statistics
if events:
total_events = collection.count_documents({})
today_events = collection.count_documents({
"timestamp": {
"$gte": datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
}
})
# Display stats
st.markdown("""
<div class="stats-container">
<div class="stat-card">
<div class="stat-number">{}</div>
<div class="stat-label">Total Events</div>
</div>
<div class="stat-card">
<div class="stat-number">{}</div>
<div class="stat-label">Today's Events</div>
</div>
<div class="stat-card">
<div class="stat-number">{}</div>
<div class="stat-label">Recent Activities</div>
</div>
</div>
""".format(total_events, today_events, len(events)), unsafe_allow_html=True)
# Display events
if events:
st.markdown("### πŸ“‹ Recent Activities")
for event in events:
# Determine icon based on event type
if "pushed" in event['message']:
icon = "πŸ“€"
elif "pull request" in event['message']:
icon = "πŸ”„"
elif "merged" in event['message']:
icon = "βœ…"
else:
icon = "πŸ“"
# Format timestamp
event_time = event.get('timestamp', datetime.datetime.now())
if isinstance(event_time, datetime.datetime):
time_str = event_time.strftime("%B %d, %Y at %I:%M %p UTC")
else:
time_str = "Unknown time"
st.markdown(f"""
<div class="activity-card">
<div class="activity-text">
<span class="activity-icon">{icon}</span>
{event['message']}
</div>
<div class="activity-time">⏰ {time_str}</div>
</div>
""", unsafe_allow_html=True)
else:
st.markdown("""
<div class="no-events">
<h3>🌟 No GitHub events yet!</h3>
<p>Your repository activities will appear here once you set up the webhook.</p>
<p>Push some code or create a pull request to see the magic happen! ✨</p>
</div>
""", unsafe_allow_html=True)
except Exception as e:
st.error(f"Error fetching events: {e}")
st.markdown("""
<div class="no-events">
<h3>⚠️ Connection Issue</h3>
<p>Unable to fetch events from the database.</p>
<p>Please check your connection and try again.</p>
</div>
""", unsafe_allow_html=True)
else:
st.markdown("""
<div class="no-events">
<h3>❌ Database Connection Failed</h3>
<p>Unable to connect to MongoDB. Please check your connection string.</p>
<p>Make sure your MONGODB_URI environment variable is set correctly.</p>
</div>
""", unsafe_allow_html=True)
# Footer
st.markdown("---")
st.markdown(
"<div style='text-align: center; color: #6b7280; padding: 1rem;'>"
"Built with ❀️ using Streamlit and FastAPI | "
f"Last updated: {datetime.datetime.now().strftime('%H:%M:%S UTC')}"
"</div>",
unsafe_allow_html=True
)
# Auto-refresh functionality (optional)
if auto_refresh:
import time
time.sleep(30)
st.rerun()