Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -5,9 +5,10 @@ from datetime import datetime, timedelta
|
|
| 5 |
import time
|
| 6 |
import os
|
| 7 |
|
| 8 |
-
def fetch_github_users(github_token=None, max_users=
|
| 9 |
"""
|
| 10 |
Fetch GitHub users from UAE directly using GitHub API
|
|
|
|
| 11 |
"""
|
| 12 |
# Read token from environment variable if not provided
|
| 13 |
if not github_token:
|
|
@@ -63,13 +64,16 @@ def fetch_github_users(github_token=None, max_users=256, min_followers=34):
|
|
| 63 |
# Count push events as contributions
|
| 64 |
contributions = len([e for e in events if e.get('type') == 'PushEvent'])
|
| 65 |
|
|
|
|
|
|
|
|
|
|
| 66 |
all_users.append({
|
| 67 |
'login': user_data.get('login', ''),
|
| 68 |
'name': user_data.get('name', user_data.get('login', '')),
|
| 69 |
'avatar': user_data.get('avatar_url', ''),
|
| 70 |
'followers': user_data.get('followers', 0),
|
| 71 |
'public_repos': user_data.get('public_repos', 0),
|
| 72 |
-
'contributions':
|
| 73 |
'location': user_data.get('location', ''),
|
| 74 |
'bio': user_data.get('bio', ''),
|
| 75 |
'company': user_data.get('company', ''),
|
|
@@ -77,7 +81,7 @@ def fetch_github_users(github_token=None, max_users=256, min_followers=34):
|
|
| 77 |
|
| 78 |
time.sleep(0.5) # Rate limiting
|
| 79 |
|
| 80 |
-
if len(all_users) >= max_users:
|
| 81 |
break
|
| 82 |
|
| 83 |
status_updates.append(f"β
Found {len(users)} users in {location}")
|
|
@@ -89,25 +93,28 @@ def fetch_github_users(github_token=None, max_users=256, min_followers=34):
|
|
| 89 |
else:
|
| 90 |
status_updates.append(f"β Error searching {location}: {response.status_code}")
|
| 91 |
|
| 92 |
-
if len(all_users) >= max_users:
|
| 93 |
break
|
| 94 |
|
| 95 |
-
# Sort by followers
|
| 96 |
-
all_users.sort(key=lambda x: (x['
|
|
|
|
|
|
|
|
|
|
| 97 |
|
| 98 |
-
# Add rank
|
| 99 |
-
for i, user in enumerate(
|
| 100 |
user['rank'] = i
|
| 101 |
|
| 102 |
# Convert to DataFrame
|
| 103 |
-
df = pd.DataFrame(
|
| 104 |
|
| 105 |
if not df.empty:
|
| 106 |
-
display_df = df[['rank', 'name', 'login', '
|
| 107 |
-
display_df.columns = ['Rank', 'Name', 'Username', 'Followers', 'Public Repos', '
|
| 108 |
display_df['GitHub Profile'] = df['login'].apply(lambda x: f"https://github.com/{x}")
|
| 109 |
|
| 110 |
-
status_message = f"β
Successfully fetched {len(df)}
|
| 111 |
return display_df, status_message
|
| 112 |
else:
|
| 113 |
return pd.DataFrame(), "β οΈ No users found\n" + "\n".join(status_updates)
|
|
@@ -131,11 +138,11 @@ def search_users(df, search_term):
|
|
| 131 |
return df[mask]
|
| 132 |
|
| 133 |
# Create Gradio interface
|
| 134 |
-
with gr.Blocks(theme=gr.themes.Soft(), title="GitHub UAE
|
| 135 |
|
| 136 |
gr.Markdown("""
|
| 137 |
-
# π GitHub
|
| 138 |
-
###
|
| 139 |
|
| 140 |
**Note:** The app will automatically use `GITHUB_TOKEN` environment variable if set.
|
| 141 |
Without a token, you're limited to 60 requests/hour. With a token: 5000 requests/hour.
|
|
@@ -149,25 +156,25 @@ with gr.Blocks(theme=gr.themes.Soft(), title="GitHub UAE Users Fetcher") as app:
|
|
| 149 |
scale=3
|
| 150 |
)
|
| 151 |
max_users_input = gr.Slider(
|
| 152 |
-
label="Max
|
| 153 |
minimum=10,
|
| 154 |
maximum=500,
|
| 155 |
-
value=
|
| 156 |
-
step=
|
| 157 |
scale=1
|
| 158 |
)
|
| 159 |
|
| 160 |
with gr.Row():
|
| 161 |
min_followers_input = gr.Slider(
|
| 162 |
-
label="Minimum Followers",
|
| 163 |
minimum=1,
|
| 164 |
maximum=100,
|
| 165 |
-
value=
|
| 166 |
step=1
|
| 167 |
)
|
| 168 |
|
| 169 |
with gr.Row():
|
| 170 |
-
fetch_btn = gr.Button("π Fetch
|
| 171 |
|
| 172 |
status_msg = gr.Textbox(label="Status", interactive=False, lines=3)
|
| 173 |
|
|
@@ -184,7 +191,7 @@ with gr.Blocks(theme=gr.themes.Soft(), title="GitHub UAE Users Fetcher") as app:
|
|
| 184 |
|
| 185 |
# Display dataframe
|
| 186 |
data_display = gr.Dataframe(
|
| 187 |
-
headers=["Rank", "Name", "Username", "Followers", "Public Repos", "
|
| 188 |
datatype=["number", "str", "str", "number", "number", "number", "str", "str"],
|
| 189 |
wrap=True,
|
| 190 |
interactive=False
|
|
@@ -192,6 +199,11 @@ with gr.Blocks(theme=gr.themes.Soft(), title="GitHub UAE Users Fetcher") as app:
|
|
| 192 |
|
| 193 |
gr.Markdown("""
|
| 194 |
---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 195 |
**How to set up GitHub Token:**
|
| 196 |
|
| 197 |
**Option 1: Environment Variable (Recommended)**
|
|
|
|
| 5 |
import time
|
| 6 |
import os
|
| 7 |
|
| 8 |
+
def fetch_github_users(github_token=None, max_users=200, min_followers=10):
|
| 9 |
"""
|
| 10 |
Fetch GitHub users from UAE directly using GitHub API
|
| 11 |
+
Sorted by contributions (primary) and followers (secondary)
|
| 12 |
"""
|
| 13 |
# Read token from environment variable if not provided
|
| 14 |
if not github_token:
|
|
|
|
| 64 |
# Count push events as contributions
|
| 65 |
contributions = len([e for e in events if e.get('type') == 'PushEvent'])
|
| 66 |
|
| 67 |
+
# Calculate total contributions
|
| 68 |
+
total_contributions = contributions + user_data.get('public_repos', 0)
|
| 69 |
+
|
| 70 |
all_users.append({
|
| 71 |
'login': user_data.get('login', ''),
|
| 72 |
'name': user_data.get('name', user_data.get('login', '')),
|
| 73 |
'avatar': user_data.get('avatar_url', ''),
|
| 74 |
'followers': user_data.get('followers', 0),
|
| 75 |
'public_repos': user_data.get('public_repos', 0),
|
| 76 |
+
'contributions': total_contributions,
|
| 77 |
'location': user_data.get('location', ''),
|
| 78 |
'bio': user_data.get('bio', ''),
|
| 79 |
'company': user_data.get('company', ''),
|
|
|
|
| 81 |
|
| 82 |
time.sleep(0.5) # Rate limiting
|
| 83 |
|
| 84 |
+
if len(all_users) >= max_users * 2: # Fetch more to ensure we get top contributors
|
| 85 |
break
|
| 86 |
|
| 87 |
status_updates.append(f"β
Found {len(users)} users in {location}")
|
|
|
|
| 93 |
else:
|
| 94 |
status_updates.append(f"β Error searching {location}: {response.status_code}")
|
| 95 |
|
| 96 |
+
if len(all_users) >= max_users * 2:
|
| 97 |
break
|
| 98 |
|
| 99 |
+
# Sort by CONTRIBUTIONS FIRST (descending), then by followers (descending)
|
| 100 |
+
all_users.sort(key=lambda x: (x['contributions'], x['followers']), reverse=True)
|
| 101 |
+
|
| 102 |
+
# Take top contributors based on max_users
|
| 103 |
+
top_users = all_users[:max_users]
|
| 104 |
|
| 105 |
+
# Add rank based on contribution order
|
| 106 |
+
for i, user in enumerate(top_users, 1):
|
| 107 |
user['rank'] = i
|
| 108 |
|
| 109 |
# Convert to DataFrame
|
| 110 |
+
df = pd.DataFrame(top_users)
|
| 111 |
|
| 112 |
if not df.empty:
|
| 113 |
+
display_df = df[['rank', 'name', 'login', 'contributions', 'followers', 'public_repos', 'location']].copy()
|
| 114 |
+
display_df.columns = ['Rank', 'Name', 'Username', 'Contributions', 'Followers', 'Public Repos', 'Location']
|
| 115 |
display_df['GitHub Profile'] = df['login'].apply(lambda x: f"https://github.com/{x}")
|
| 116 |
|
| 117 |
+
status_message = f"β
Successfully fetched top {len(df)} contributors (sorted by contributions)\n" + "\n".join(status_updates[-5:])
|
| 118 |
return display_df, status_message
|
| 119 |
else:
|
| 120 |
return pd.DataFrame(), "β οΈ No users found\n" + "\n".join(status_updates)
|
|
|
|
| 138 |
return df[mask]
|
| 139 |
|
| 140 |
# Create Gradio interface
|
| 141 |
+
with gr.Blocks(theme=gr.themes.Soft(), title="GitHub UAE Top Contributors") as app:
|
| 142 |
|
| 143 |
gr.Markdown("""
|
| 144 |
+
# π Top 200 GitHub Contributors in UAE
|
| 145 |
+
### Ranked by Total Contributions (Public Repos + Recent Push Events)
|
| 146 |
|
| 147 |
**Note:** The app will automatically use `GITHUB_TOKEN` environment variable if set.
|
| 148 |
Without a token, you're limited to 60 requests/hour. With a token: 5000 requests/hour.
|
|
|
|
| 156 |
scale=3
|
| 157 |
)
|
| 158 |
max_users_input = gr.Slider(
|
| 159 |
+
label="Max Contributors",
|
| 160 |
minimum=10,
|
| 161 |
maximum=500,
|
| 162 |
+
value=200,
|
| 163 |
+
step=10,
|
| 164 |
scale=1
|
| 165 |
)
|
| 166 |
|
| 167 |
with gr.Row():
|
| 168 |
min_followers_input = gr.Slider(
|
| 169 |
+
label="Minimum Followers (for initial search)",
|
| 170 |
minimum=1,
|
| 171 |
maximum=100,
|
| 172 |
+
value=10,
|
| 173 |
step=1
|
| 174 |
)
|
| 175 |
|
| 176 |
with gr.Row():
|
| 177 |
+
fetch_btn = gr.Button("π Fetch Top Contributors from GitHub", variant="primary", size="lg")
|
| 178 |
|
| 179 |
status_msg = gr.Textbox(label="Status", interactive=False, lines=3)
|
| 180 |
|
|
|
|
| 191 |
|
| 192 |
# Display dataframe
|
| 193 |
data_display = gr.Dataframe(
|
| 194 |
+
headers=["Rank", "Name", "Username", "Contributions", "Followers", "Public Repos", "Location", "GitHub Profile"],
|
| 195 |
datatype=["number", "str", "str", "number", "number", "number", "str", "str"],
|
| 196 |
wrap=True,
|
| 197 |
interactive=False
|
|
|
|
| 199 |
|
| 200 |
gr.Markdown("""
|
| 201 |
---
|
| 202 |
+
**Ranking Criteria:**
|
| 203 |
+
- **Primary Sort:** Total Contributions (Public Repos + Recent Push Events)
|
| 204 |
+
- **Secondary Sort:** Followers count
|
| 205 |
+
- Only users from UAE locations are included
|
| 206 |
+
|
| 207 |
**How to set up GitHub Token:**
|
| 208 |
|
| 209 |
**Option 1: Environment Variable (Recommended)**
|