Skip to content

Commit 10c7a16

Browse files
authored
Merge pull request #277 from shubhagarwal1/clog
Add Scrape ML Changelog Dashboard and Merged PR Statistics
2 parents f3690b8 + 794435c commit 10c7a16

File tree

1 file changed

+284
-0
lines changed

1 file changed

+284
-0
lines changed

Web_app/pages/ChangeLog.py

Lines changed: 284 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,284 @@
1+
import streamlit as st
2+
import requests
3+
from datetime import datetime
4+
import pandas as pd
5+
6+
# GitHub repository URL
7+
REPO_URL = "https://api.github.com/repos/recodehive/Scrape-ML"
8+
9+
10+
# Function to fetch repository statistics
11+
def fetch_repo_statistics():
12+
closed_pr_count = fetch_closed_pr_count()
13+
return {
14+
"total_prs": closed_pr_count,
15+
"total_projects": fetch_total_projects(),
16+
"total_contributors": fetch_contributors_count(),
17+
}
18+
19+
20+
# Existing fetch functions remain the same
21+
def fetch_closed_pr_count():
22+
closed_prs_url = f"{REPO_URL}/pulls?state=closed"
23+
closed_pr_count = 0
24+
page = 1
25+
while True:
26+
response = requests.get(f"{closed_prs_url}&page={page}")
27+
if response.status_code != 200 or not response.json():
28+
break
29+
closed_pr_count += len(response.json())
30+
page += 1
31+
return closed_pr_count
32+
33+
34+
def fetch_total_projects():
35+
return 0
36+
37+
38+
def fetch_closed_prs():
39+
closed_prs_url = f"{REPO_URL}/pulls?state=closed"
40+
closed_prs = []
41+
page = 1
42+
while True:
43+
response = requests.get(f"{closed_prs_url}&page={page}")
44+
if response.status_code != 200 or not response.json():
45+
break
46+
pulls = response.json()
47+
for pr in pulls:
48+
if pr["merged_at"]:
49+
closed_prs.append(
50+
{
51+
"title": pr["title"],
52+
"url": pr["html_url"],
53+
"date": pr["merged_at"],
54+
"user": pr["user"]["login"],
55+
"avatar_url": pr["user"]["avatar_url"],
56+
}
57+
)
58+
page += 1
59+
return closed_prs
60+
61+
62+
def fetch_upcoming_issues():
63+
issues_url = f"{REPO_URL}/issues?state=open"
64+
upcoming_issues = []
65+
response = requests.get(issues_url)
66+
if response.status_code == 200:
67+
issues = response.json()
68+
for issue in issues:
69+
if issue.get("assignee"):
70+
upcoming_issues.append(
71+
{
72+
"title": issue["title"],
73+
"url": issue["html_url"],
74+
"date": issue["created_at"],
75+
"assignee": issue["assignee"]["login"],
76+
"avatar_url": issue["assignee"]["avatar_url"],
77+
}
78+
)
79+
return upcoming_issues
80+
81+
82+
def fetch_contributors_count():
83+
contributors_url = f"{REPO_URL}/contributors"
84+
response = requests.get(contributors_url)
85+
if response.status_code == 200:
86+
return len(response.json())
87+
return 0
88+
89+
90+
# Custom CSS for modern design
91+
st.set_page_config(
92+
page_title="Changelog - Scrape ML",
93+
page_icon="📝",
94+
layout="wide",
95+
initial_sidebar_state="expanded",
96+
)
97+
98+
# Custom CSS
99+
st.markdown(
100+
"""
101+
<style>
102+
/* Modern card design */
103+
.css-1r6slb0 {
104+
background-color: #ffffff;
105+
border-radius: 10px;
106+
padding: 20px;
107+
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
108+
}
109+
110+
/* Timeline design */
111+
.timeline-item {
112+
position: relative;
113+
padding: 20px;
114+
margin: 20px 0;
115+
background: white;
116+
border-radius: 10px;
117+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
118+
color: black;
119+
}
120+
121+
.timeline-item::before {
122+
content: '';
123+
position: absolute;
124+
left: -8px;
125+
top: 50%;
126+
width: 16px;
127+
height: 16px;
128+
background: #6c5ce7;
129+
border-radius: 50%;
130+
transform: translateY(-50%);
131+
}
132+
133+
/* Stats cards */
134+
.stat-card {
135+
background: white;
136+
padding: 20px;
137+
border-radius: 10px;
138+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
139+
text-align: center;
140+
}
141+
142+
.stat-number {
143+
font-size: 2.5em;
144+
font-weight: bold;
145+
color: #6c5ce7;
146+
}
147+
148+
.stat-label {
149+
color: #666;
150+
font-size: 1.1em;
151+
}
152+
153+
/* Avatar style */
154+
.avatar-small {
155+
border-radius: 50%;
156+
width: 30px;
157+
height: 30px;
158+
margin-right: 10px;
159+
vertical-align: middle;
160+
}
161+
162+
/* Progress bar */
163+
.stProgress > div > div > div > div {
164+
background-color: #6c5ce7;
165+
}
166+
</style>
167+
""",
168+
unsafe_allow_html=True,
169+
)
170+
171+
# Title with gradient
172+
st.markdown(
173+
"""
174+
<h1 style='text-align: center; background: linear-gradient(45deg, #6c5ce7, #a8c0ff);
175+
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
176+
margin-bottom: 30px;'>
177+
Scrape ML Changelog 📝
178+
</h1>
179+
""",
180+
unsafe_allow_html=True,
181+
)
182+
183+
# Fetch data
184+
repo_stats = fetch_repo_statistics()
185+
closed_prs = fetch_closed_prs()
186+
upcoming_issues = fetch_upcoming_issues()
187+
188+
# Stats dashboard
189+
st.markdown("### Project Statistics")
190+
cols = st.columns(4)
191+
192+
with cols[0]:
193+
st.markdown(
194+
"""
195+
<div class='stat-card'>
196+
<div class='stat-number'>{}</div>
197+
<div class='stat-label'>PRs Merged</div>
198+
</div>
199+
""".format(
200+
repo_stats["total_prs"]
201+
),
202+
unsafe_allow_html=True,
203+
)
204+
205+
with cols[1]:
206+
st.markdown(
207+
"""
208+
<div class='stat-card'>
209+
<div class='stat-number'>{}</div>
210+
<div class='stat-label'>Contributors</div>
211+
</div>
212+
""".format(
213+
repo_stats["total_contributors"]
214+
),
215+
unsafe_allow_html=True,
216+
)
217+
218+
# Timeline section
219+
st.markdown("### Recent Activity Timeline")
220+
221+
for pr in closed_prs[:5]: # Show only last 5 PRs
222+
date = datetime.strptime(pr["date"], "%Y-%m-%dT%H:%M:%SZ").strftime("%B %d, %Y")
223+
st.markdown(
224+
f"""
225+
<div class='timeline-item'>
226+
<img src='{pr['avatar_url']}' class='avatar-small'>
227+
<strong>{pr['user']}</strong> merged PR:
228+
<a href='{pr['url']}' target='_blank'>{pr['title']}</a>
229+
<div style='color: #666; font-size: 0.9em; margin-top: 5px;'>{date}</div>
230+
</div>
231+
""",
232+
unsafe_allow_html=True,
233+
)
234+
235+
# Upcoming Features
236+
st.markdown("### 🚀 Upcoming Features")
237+
cols = st.columns(3)
238+
239+
upcoming_features = [
240+
{
241+
"title": "Personalized Watchlist",
242+
"progress": 75,
243+
"desc": "Implementation of user preferences-based watchlist",
244+
},
245+
{
246+
"title": "External DB Integration",
247+
"progress": 45,
248+
"desc": "Integration with external movie databases",
249+
},
250+
{
251+
"title": "Advanced Filtering",
252+
"progress": 30,
253+
"desc": "Enhanced search and filter capabilities",
254+
},
255+
]
256+
257+
for idx, feature in enumerate(upcoming_features):
258+
with cols[idx]:
259+
st.markdown(
260+
f"""
261+
<div style='background: white; padding: 20px; border-radius: 10px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);'>
262+
<h4>{feature['title']}</h4>
263+
<p style='color: black; font-size: 0.9em;'>{feature['desc']}</p>
264+
</div>
265+
""",
266+
unsafe_allow_html=True,
267+
)
268+
st.progress(feature["progress"] / 100)
269+
270+
# Footer
271+
st.markdown("---")
272+
st.markdown(
273+
"""
274+
<div style='text-align: center; padding: 20px;'>
275+
<h3 style='color: #6c5ce7;'>About Scrape ML</h3>
276+
<p>Scrape ML is a robust web scraping tool designed to simplify the extraction of data from various online sources.
277+
With its user-friendly interface and powerful features, Scrape ML allows users to collect, organize,
278+
and analyze data seamlessly. Ideal for developers, data scientists, and anyone interested in leveraging
279+
web data for their projects.</p>
280+
<p style='color: #666; margin-top: 20px;'>Made with 💜 by the Scrape ML Team</p>
281+
</div>
282+
""",
283+
unsafe_allow_html=True,
284+
)

0 commit comments

Comments
 (0)