Created
June 22, 2025 05:36
-
-
Save 0xbharath/3b6c4f11689d288d8b42e81e56e63ff6 to your computer and use it in GitHub Desktop.
IndiaFOSS Proposal Approvals Tracking
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import re | |
from multiprocessing import Pool | |
from playwright.sync_api import sync_playwright | |
from tabulate import tabulate | |
def fetch_approval(workshop): | |
title, url = workshop | |
with sync_playwright() as p: | |
browser = p.chromium.launch(headless=True) | |
context = browser.new_context() | |
page = context.new_page() | |
try: | |
page.goto(url, timeout=10000) | |
page.wait_for_load_state("domcontentloaded") | |
try: | |
page.wait_for_selector("div.flex.text-green-600", timeout=3000) | |
approval_span = page.locator("div.flex.text-green-600 span.text-xl.font-bold").first | |
approvals = approval_span.inner_text().strip() | |
except: | |
approvals = "?" | |
except Exception as e: | |
print(f"⚠️ Error for {title}: {e}") | |
approvals = "?" | |
finally: | |
context.close() | |
browser.close() | |
return (title, approvals) | |
def run(): | |
with sync_playwright() as p: | |
browser = p.chromium.launch(headless=True) | |
context = browser.new_context() | |
page = context.new_page() | |
# Step 1: Go to proposals page | |
page.goto("https://fossunited.org/dashboard/cfp/all/indiafoss/2025") | |
# Step 2: Apply Workshop filter | |
page.get_by_role("button", name="Filter").click() | |
page.locator("div").filter(has_text=re.compile(r"^Add filter$")).first.click() | |
page.get_by_role("button", name="Add filter").click() | |
page.get_by_text("Session Type").click() | |
page.locator("#frappe-ui-3").select_option("Workshop") | |
# Step 3: Wait for proposals to load | |
page.wait_for_selector("a[href^='/c/indiafoss/2025/cfp/'] h4") | |
# Step 4: Extract titles and URLs | |
proposal_links = page.query_selector_all("a[href^='/c/indiafoss/2025/cfp/']") | |
workshops = [] | |
for a_tag in proposal_links: | |
try: | |
href = a_tag.get_attribute("href") | |
h4_elem = a_tag.query_selector("h4") | |
title = h4_elem.inner_text().strip() if h4_elem else "Untitled" | |
if href: | |
full_url = "https://fossunited.org" + href | |
workshops.append((title, full_url)) | |
except Exception as e: | |
print("⚠️ Skipping one due to:", e) | |
context.close() | |
browser.close() | |
# Step 5: Parallel fetch approvals | |
print(f"\n🔄 Fetching {len(workshops)} workshop approvals in parallel...\n") | |
with Pool(processes=5) as pool: | |
results = pool.map(fetch_approval, workshops) | |
# Step 6: Sort by approval count | |
sorted_results = sorted( | |
results, | |
key=lambda x: int(x[1]) if x[1].isdigit() else 0, | |
reverse=True | |
) | |
# Step 7: Display results | |
print("\n📋 Workshop Approvals Table (Sorted by Approvals):\n") | |
print(tabulate(sorted_results, headers=["Workshop Title", "Approvals"], tablefmt="github")) | |
if __name__ == "__main__": | |
run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment