|
import os |
|
import requests |
|
from io import BytesIO |
|
from datetime import date |
|
|
|
import gradio as gr |
|
from PIL import Image, ImageDraw, ImageFont |
|
from huggingface_hub import whoami |
|
|
|
from criteria import check_certification as check_certification_criteria |
|
from org import join_finishers_org |
|
|
|
|
|
def download_profile_picture(profile_url: str): |
|
"""Download profile picture from URL.""" |
|
response = requests.get(profile_url) |
|
return Image.open(BytesIO(response.content)) |
|
|
|
|
|
def generate_certificate( |
|
certificate_path: str, first_name: str, last_name: str, profile_url: str |
|
): |
|
"""Generate certificate image and PDF.""" |
|
im = Image.open(certificate_path) |
|
d = ImageDraw.Draw(im) |
|
|
|
name_font = ImageFont.truetype("Quattrocento-Regular.ttf", 100) |
|
date_font = ImageFont.truetype("Quattrocento-Regular.ttf", 48) |
|
|
|
name = f"{first_name} {last_name}" |
|
|
|
|
|
name = name.title() |
|
|
|
|
|
d.text((1000, 740), name, fill="black", anchor="mm", font=name_font) |
|
|
|
|
|
profile_img = download_profile_picture(profile_url) |
|
profile_img = profile_img.resize((100, 100)) |
|
im.paste(im=profile_img, box=(350, 700)) |
|
|
|
|
|
d.text((1480, 1170), str(date.today()), fill="black", anchor="mm", font=date_font) |
|
|
|
|
|
pdf = im.convert("RGB") |
|
pdf.save("certificate.pdf") |
|
|
|
return im, "./certificate.pdf" |
|
|
|
|
|
def get_user_info(oauth_token): |
|
"""Get user info from HF token.""" |
|
if oauth_token is None: |
|
return None, None, None, None |
|
try: |
|
user_info = whoami(oauth_token.token) |
|
username = user_info["name"] |
|
name_parts = user_info["fullname"].split(" ", 1) |
|
first_name = name_parts[0] |
|
last_name = name_parts[1] if len(name_parts) > 1 else "" |
|
profile_url = user_info["avatarUrl"] |
|
return username, first_name, last_name, profile_url |
|
except: |
|
return None, None, None, None |
|
|
|
|
|
def create_linkedin_button(username: str) -> str: |
|
"""Create LinkedIn 'Add to Profile' button HTML.""" |
|
current_year = date.today().year |
|
current_month = date.today().month |
|
|
|
|
|
cert_url = "https://huggingface.co/agents-course-finishers" |
|
|
|
linkedin_params = { |
|
"startTask": "CERTIFICATION_NAME", |
|
"name": "Hugging Face Course Certificate", |
|
|
|
"organizationName": "Hugging Face", |
|
"issueYear": str(current_year), |
|
"issueMonth": str(current_month), |
|
"certUrl": cert_url, |
|
"certId": username, |
|
} |
|
|
|
|
|
base_url = "https://www.linkedin.com/profile/add?" |
|
params = "&".join( |
|
f"{k}={requests.utils.quote(v)}" for k, v in linkedin_params.items() |
|
) |
|
button_url = base_url + params |
|
|
|
return f""" |
|
<a href="{button_url}" target="_blank" style="display: block; margin-top: 20px; text-align: center;"> |
|
<img src="https://download.linkedin.com/desktop/add2profile/buttons/en_US.png" |
|
alt="LinkedIn Add to Profile button"> |
|
</a> |
|
""" |
|
|
|
|
|
def check_certification(token: gr.OAuthToken | None): |
|
"""Check certification status for logged-in user.""" |
|
if token is None: |
|
gr.Warning("Please log in to Hugging Face before checking certification!") |
|
return None, None, None, gr.Row.update(visible=False) |
|
|
|
username, first_name, last_name, profile_url = get_user_info(token) |
|
if not username: |
|
return ( |
|
"Please login with your Hugging Face account to check certification status", |
|
None, |
|
None, |
|
gr.Row.update(visible=False), |
|
) |
|
|
|
|
|
result = check_certification_criteria(username) |
|
|
|
|
|
if result.passed and result.certificate_path: |
|
certificate_img, pdf_path = generate_certificate( |
|
certificate_path=result.certificate_path, |
|
first_name=first_name, |
|
last_name=last_name, |
|
profile_url=profile_url, |
|
) |
|
|
|
|
|
linkedin_button = create_linkedin_button(username) |
|
result_message = f"{result.message}\n\n{linkedin_button}" |
|
else: |
|
certificate_img = None |
|
pdf_path = None |
|
result_message = result.message |
|
|
|
return ( |
|
gr.update(visible=True, value=result_message, label="Grade"), |
|
gr.update(visible=result.passed, value=pdf_path, label="Download Certificate"), |
|
gr.update(visible=result.passed, value=certificate_img, label="Certificate"), |
|
) |
|
|
|
|
|
def create_gradio_interface(): |
|
"""Create Gradio web interface with OAuth login.""" |
|
with gr.Blocks() as demo: |
|
gr.Markdown(""" |
|
# Get your Hugging Face Course Certificate 🎓 |
|
The certification process is completely free. |
|
|
|
To receive your certificate, you need to **pass 80% of the quiz**. |
|
|
|
There's **no deadlines, the course is self-paced**. |
|
|
|
Don't hesitate to share your certificate on Twitter |
|
(tag @huggingface) and on Linkedin. |
|
""") |
|
|
|
|
|
gr.LoginButton() |
|
|
|
check_progress_button = gr.Button(value="Check My Progress") |
|
|
|
output_text = gr.Markdown(visible=False, sanitize_html=False) |
|
output_img = gr.Image(type="pil", visible=False) |
|
output_pdf = gr.File(visible=False) |
|
|
|
check_progress_button.click( |
|
fn=check_certification, |
|
outputs=[output_text, output_pdf, output_img], |
|
).then( |
|
fn=join_finishers_org, |
|
) |
|
|
|
return demo |
|
|
|
|
|
if __name__ == "__main__": |
|
demo = create_gradio_interface() |
|
demo.launch(debug=True) |
|
|