Spaces:
Sleeping
Sleeping
import gradio as gr | |
from datasets import load_dataset | |
import pandas as pd | |
from jinja2 import Template | |
import datetime | |
import random | |
import weasyprint | |
import requests | |
from bs4 import BeautifulSoup | |
css = ''' | |
.gradio-container{max-width: 1300px !important} | |
h1{text-align:center} | |
.submit-btn { | |
background-color: #a753be !important; | |
color: white !important; | |
} | |
.submit-btn:hover { | |
background-color: #d94eff !important; | |
} | |
''' | |
dataset = load_dataset("maxiw/hf-posts", split="train") | |
df = pd.DataFrame(dataset) | |
df["Name"] = df["author"].apply(lambda x: x["fullname"]) | |
df["username"] = df["author"].apply(lambda x: x["name"]) | |
df["totalReactions"] = df["reactions"].apply(lambda x: sum([_["count"] for _ in x])) | |
df["Num of posts"] = 1 | |
metrics = ["totalUniqueImpressions", "totalReactions", "numComments", "Num of posts"] | |
data = ( | |
df.groupby(["username", "Name"])[metrics] | |
.sum() | |
.reset_index() | |
) | |
data["Rank"] = data["totalUniqueImpressions"].rank(method="min", ascending=False).astype(int) | |
receipt_template = """ | |
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>HuggingFace Receipt</title> | |
<style> | |
body { | |
font-family: Arial, sans-serif; | |
background-color: #f4f4f9; | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
height: 100vh; | |
margin: 0; | |
} | |
.receipt { | |
background-color: #fff; | |
padding: 20px; | |
border-radius: 8px; | |
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); | |
width: 300px; | |
text-align: center; | |
} | |
.title { | |
font-size: 24px; | |
font-weight: bold; | |
margin-bottom: 20px; | |
color: #007bff; | |
} | |
.subtitle { | |
font-size: 18px; | |
font-weight: bold; | |
margin-bottom: 20px; | |
color: #333; | |
} | |
.section-heading { | |
font-size: 16px; | |
font-weight: bold; | |
margin-top: 20px; | |
margin-bottom: 10px; | |
color: #333; | |
} | |
.label { | |
font-size: 14px; | |
font-weight: bold; | |
text-align: left; | |
margin-bottom: 5px; | |
color: #555; | |
} | |
.value { | |
font-size: 14px; | |
text-align: left; | |
margin-bottom: 10px; | |
color: #333; | |
} | |
.table { | |
width: 100%; | |
border-collapse: collapse; | |
margin-top: 20px; | |
} | |
.table th, .table td { | |
border: 1px solid #ddd; | |
padding: 8px; | |
text-align: left; | |
} | |
.table th { | |
background-color: #007bff; | |
color: #fff; | |
font-weight: bold; | |
} | |
.footer { | |
font-size: 12px; | |
margin-top: 20px; | |
color: #555; | |
} | |
.profile-photo { | |
width: 100px; | |
height: 100px; | |
border-radius: 50%; | |
margin: 0 auto 20px; | |
display: block; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="receipt"> | |
<div class="title">#HF_POSTS🤗</div> | |
<div class="subtitle">{{ current_date }}</div> | |
<div class="subtitle">ORDER #{{ order_id }}</div> | |
<img class="profile-photo" src="{{ profile_photo }}" alt="Profile Photo"> | |
<div class="section-heading">{{ user_name }}</div> | |
<div class="label">User Name:</div> | |
<div class="value">{{ username }}</div> | |
<table class="table"> | |
<thead> | |
<tr> | |
<th>Details</th> | |
<th>Value</th> | |
</tr> | |
</thead> | |
<tbody> | |
<tr> | |
<td>NO. OF POSTS</td> | |
<td>{{ num_posts }}</td> | |
</tr> | |
<tr> | |
<td>REACTIONS EARNED</td> | |
<td>{{ total_reactions }}</td> | |
</tr> | |
<tr> | |
<td>TOTAL COMMENTS</td> | |
<td>{{ num_comments }}</td> | |
</tr> | |
<tr> | |
<td>IMPRESSIONS</td> | |
<td>{{ total_impressions }}</td> | |
</tr> | |
<tr> | |
<td>RANKING</td> | |
<td>{{ rank }}</td> | |
</tr> | |
</tbody> | |
</table> | |
<div class="section-heading">Thank you for using HuggingFace!</div> | |
<div class="footer">AI community building the future</div> | |
<div class="footer">THANKS FOR YAPPING!</div> | |
<div class="footer"><a href="https://huggingface.co/{{ username }}" target="_blank">huggingface.co/{{ username }}</a></div> | |
</div> | |
</body> | |
</html> | |
""" | |
def fetch_profile_photo(username): | |
url = f"https://huggingface.co/{username}" | |
response = requests.get(url) | |
soup = BeautifulSoup(response.content, 'html.parser') | |
img_tag = soup.find('img', {'class': 'h-32 w-32 overflow-hidden rounded-full shadow-inner lg:h-48 lg:w-48'}) | |
if img_tag: | |
return img_tag['src'] | |
return None | |
def generate_receipt(username): | |
user_data = data[data['username'] == username] | |
if user_data.empty: | |
return "User not found" | |
else: | |
current_date = datetime.datetime.now().strftime("%A, %B %d, %Y") | |
current_time = datetime.datetime.now().strftime("%I:%M:%S %p") | |
order_id = random.randint(1000, 9999) | |
user_name = user_data['Name'].values[0] | |
profile_photo = fetch_profile_photo(username) | |
num_posts = user_data['Num of posts'].values[0] | |
total_reactions = user_data['totalReactions'].values[0] | |
num_comments = user_data['numComments'].values[0] | |
total_impressions = user_data['totalUniqueImpressions'].values[0] | |
rank = user_data['Rank'].values[0] | |
template = Template(receipt_template) | |
html_content = template.render( | |
current_date=current_date, | |
order_id=order_id, | |
user_name=user_name, | |
username=username, | |
profile_photo=profile_photo, | |
num_posts=num_posts, | |
total_reactions=total_reactions, | |
num_comments=num_comments, | |
total_impressions=total_impressions, | |
rank=rank | |
) | |
html_path = "receipt.html" | |
with open(html_path, "w") as f: | |
f.write(html_content) | |
pdf_path = "receipt.pdf" | |
weasyprint.HTML(html_path).write_pdf(pdf_path) | |
return html_path, pdf_path | |
iface = gr.Interface( | |
fn=generate_receipt, | |
inputs="text", | |
outputs=["file", "file"], | |
title="HF_POSTS_RECEIPTS 🤗", | |
description="Enter a username to generate a receipt with post details.", | |
examples=[ | |
["prithivMLmods"], | |
["clem"], | |
["maxiw"], | |
["merve"], | |
["reach-vb"], | |
["fdaudens"], | |
["akhaliq"], | |
["thomwolf"] | |
], | |
css=css, | |
theme="bethecloud/storj_theme", | |
) | |
iface.launch(share=True) |