HuggingFaceWeeklyPaper / interface.py
HowardZhangdqs's picture
chore: remove label
d91c7bd
from pathlib import Path
import gradio as gr
from datetime import datetime, timedelta
from fetch_paper import fetch_papers_with_daterange
from sorter import sort_by_upvotes, sort_by_comments, sort_by_date
from date import Date
import assets
def format_author(author):
"""Format author information"""
if not author:
return ""
hidden_status = " (hidden)" if author.hidden else ""
if author.name:
return f"<a href='https://scholar.google.com/citations?view_op=search_authors&mauthors={author.name.replace(' ', '+')}' target='_blank'>{author.name}</a>"
return "Anonymous author"
# 底部论文介绍
def format_paper_info(article):
"""Generate HTML content for paper display"""
if not article.paper:
return "Paper information missing"
info = []
# Title section
info.append(f"<h2 class='sf-paper-title' id='sf-flag'>{article.title or 'Untitled Paper'}</h2>")
info.append(f"<p style='text-align: center'>")
info.append(f"<a href='https://huggingface.co/papers/{article.paper.id}' target='_blank' class='sf-button'>Hugging Face{assets.SVG_LINK}</a>")
info.append(f"<a href='https://arxiv.org/abs/{article.paper.id}' target='_blank' class='sf-button'>arXiv{assets.SVG_LINK}</a>")
info.append(f"<a href='https://arxiv.org/pdf/{article.paper.id}' target='_blank' class='sf-button'>PDF{assets.SVG_LINK}</a>")
info.append(f"</p>")
# Thumbnail
if article.thumbnail:
info.append(f"<p><img src='{article.thumbnail}' style='max-width: 30em; width: 100%; margin: auto'/></p>")
# Basic information
info.append(
f"<p><strong>Paper ID</strong>: <a href='https://huggingface.co/papers/{article.paper.id}' target='_blank'>{article.paper.id or 'Unknown'}</a></p>")
info.append(
f"<p><strong>Published At</strong>: {article.paper.publishedAt.strftime('%Y-%m-%d %H:%M') if article.paper.publishedAt else 'Unknown'}</p>")
# Author information
authors = ", ".join([format_author(a) for a in article.paper.authors]) if article.paper.authors else "Author information not available"
info.append(f"<p><strong>Authors</strong>: {authors}</p>")
# Summary
if article.paper.summary:
summary = article.paper.summary.replace('{{', '{').replace('}}', '}').replace('\n', ' ')
info.append(f"<h3>Summary</h3><p>{summary}</p>")
# Discussion information
info.append(f"<p><strong>Upvotes</strong>: {article.paper.upvotes or 0}<span style='margin-left: .5rem'></span>")
info.append(f"<strong>Comments</strong>: {article.numComments or 0}</p>")
if article.paper.discussionId:
info.append(
f"<a href='https://huggingface.co/papers/{article.paper.id}#community' target='_blank' class='sf-button'>Join Discussion{assets.SVG_LINK}</a></p>")
# Submitter information
if article.submittedBy:
submitter = article.submittedBy
info.append(f"<hr><p><strong>Submitter</strong>: ")
avatar_url = submitter.avatarUrl if submitter.avatarUrl.startswith("http") else f"https://huggingface.co{submitter.avatarUrl}"
profile_url = f"https://huggingface.co/{submitter.name}"
info.append(
f"<span><img src='{avatar_url}' class='sf-author' /></span>{submitter.fullname}(<a href='{profile_url}' target='_blank'>@{submitter.name}</a>) ")
info.append(f"Followers: {submitter.followerCount or 0}</p>")
return "".join(info)
def generate_table_html(papers):
"""Generate table HTML with clickable titles and an extra column for arXiv abs link"""
html = ['<table class="paper-table"><thead><tr>'
'<th>Title</th>'
'<th>👍 Upvotes</th>'
'<th>💬 Comments</th>'
'<th>📅 Date</th>'
# '<th>Label</th>'
'<th></th>'
'</tr></thead><tbody>']
for article in papers:
title = article.title or "Untitled"
upvotes = article.paper.upvotes or 0
comments = article.numComments or 0
date = article.paper.publishedAt.strftime("%Y-%m-%d") if article.paper.publishedAt else "Unknown"
paper_id = article.paper.id
# label = ", ".join(article.paper.label) or ""
# 构造 arXiv abs 链接
arxiv_abs_link = f"https://huggingface.co/papers/{paper_id}"
row = f"""
<tr>
<td><a class="paper-title" href="{arxiv_abs_link}" target="_blank">{title}{assets.SVG_LINK}</a></td>
<td>{upvotes}</td>
<td>{comments}</td>
<td>{date}</td>
<td><a href="javascript:void(0)" onclick="showDetail('{paper_id}')" class="sf-button" style="margin: 0">Details{assets.SVG_LINK}</a></td>
</tr>
""" # <td>{label}</td>
html.append(row)
html.append("</tbody></table>")
return "".join(html)
def build_html(papers):
# Convert all papers to an HTML string, each paper wrapped in a div, with the div containing the paper's information, and the div's id being the paper's id
html = ""
for index, article in enumerate(papers):
article_html = format_paper_info(article)
html += f"<div id='smartflow-paper-{article.paper.id.replace('.', '-')}' style='{'' if index == 0 else 'display: none'}'>{article_html}</div>"
return html
def query_papers(start_date_str: str, end_date_str: str, sort_method: str): # Added sort_method parameter
"""Handle date range query"""
try:
start_date = Date(start_date_str)
end_date = Date(end_date_str)
papers = fetch_papers_with_daterange(start_date, end_date)
# Sort papers based on the selected sorting method
if sort_method == "Sort by upvotes ascending":
papers = sort_by_upvotes(papers, reverse=False)
elif sort_method == "Sort by upvotes descending":
papers = sort_by_upvotes(papers, reverse=True)
elif sort_method == "Sort by comments ascending":
papers = sort_by_comments(papers, reverse=False)
elif sort_method == "Sort by comments descending":
papers = sort_by_comments(papers, reverse=True)
elif sort_method == "Sort by date ascending":
papers = sort_by_date(papers, reverse=False)
elif sort_method == "Sort by date descending":
papers = sort_by_date(papers, reverse=True)
# elif sort_method == "Sort by label":
# papers = sorted(papers, key=lambda x: ", ".join(x.paper.label))
return generate_table_html(papers), build_html(papers)
except Exception as e:
print(f"Query error: {e}")
return "<p>⚠️ Query failed, please check the date format (YYYY-MM-DD)</p>", "<p>⚠️ Query failed, please check the date format (YYYY-MM-DD)</p>"
# CSS 样式(可放入单独文件)
custom_css = """
.detail-area { margin-top: 20px; padding: 20px; border: 1px solid #ddd; border-radius: 5px; }
.sf-paper-title { text-align: center; }
img.sf-author {
height: 1.3rem;
border: 1px solid #000;
vertical-align: middle;
border-radius: 50%;
display: inline;
margin: 0 0.1rem;
}
#paper-detail-area {
display: none;
}
#paper-detail-area:has(#sf-flag) {
display: block;
}
#query-results-html { min-height: 100px; }
"""
# 遍历./css文件夹下的所有文件,将文件内容作为CSS样式添加到页面中
for css_file in Path("./css").glob("*.css"):
with open(css_file, "r") as f:
custom_css += "\n" + f.read() + "\n"
custom_js = """"""
# 遍历./css文件夹下的所有文件,将文件内容作为CSS样式添加到页面中
for js_file in Path("./js").glob("*.js"):
with open(js_file, "r") as f:
custom_js += "\n" + f.read() + "\n"
def create_interface():
"""Create a new interface layout"""
with gr.Blocks(title="Hugging Face Daily Paper", css=custom_css, head=f"<script>{custom_js}</script>") as app:
# Main interface
gr.HTML("<div style='text-align: center'><h1>📚 Hugging Face Weekly Paper</h1></div>")
gr.HTML("""<div style='text-align: center'>
<span style="">
🔗 <a href='https://larkcommunity.feishu.cn/wiki/HSSTwsq7JiDur0kJrvjcnFZfnTe'>Contribute to this project</a>
</span>
<span style="margin-left: 1rem">
Sponsor: <a href='https://internlm.intern-ai.org.cn/api/document'>InternLM</a>
</span>
</div>""")
# Query control area
with gr.Row():
with gr.Column():
with gr.Row():
start_date = gr.Textbox(elem_id="start_date", label="Start Date", placeholder="YYYY-MM-DD", value=str(Date() + (-7)))
end_date = gr.Textbox(elem_id="end_date", label="End Date", placeholder="YYYY-MM-DD", value=str(Date()))
with gr.Column():
with gr.Row():
today_btn = gr.Button("Today")
last_week_btn = gr.Button("Last Week")
last_month_btn = gr.Button("Last Month")
query_btn = gr.Button("🔍 Query", variant="primary", elem_id="query_button")
with gr.Row():
# Add sorting method selection
sort_method = gr.Radio(
label="Sort Method",
choices=[
"Sort by upvotes descending",
"Sort by comments descending",
"Sort by date descending",
"Sort by upvotes ascending",
"Sort by comments ascending",
"Sort by date ascending",
# "Sort by label",
],
value="Sort by upvotes descending",
)
# Results display area
with gr.Column(visible=True):
results_html = gr.HTML(label="Query Results", elem_id="query-results-html")
# Paper details area
with gr.Column(visible=True, elem_classes="detail-area", elem_id="paper-detail-area"):
gr.Markdown("## Paper Details")
detail_html = gr.HTML(elem_id="detail-html")
# Event handling
query_btn.click(
fn=query_papers,
inputs=[start_date, end_date, sort_method],
outputs=[results_html, detail_html]
)
sort_method.change(
fn=query_papers,
inputs=[start_date, end_date, sort_method],
outputs=[results_html, detail_html]
)
# Add button event handling
today_btn.click(
fn=lambda: (str(Date()), str(Date())),
outputs=[start_date, end_date]
).then(
fn=query_papers,
inputs=[start_date, end_date, sort_method],
outputs=[results_html, detail_html]
)
last_week_btn.click(
fn=lambda: (str(Date() + (-7)), str(Date())),
outputs=[start_date, end_date]
).then(
fn=query_papers,
inputs=[start_date, end_date, sort_method],
outputs=[results_html, detail_html]
)
last_month_btn.click(
fn=lambda: (str(Date() + (-30)), str(Date())),
outputs=[start_date, end_date]
).then(
fn=query_papers,
inputs=[start_date, end_date, sort_method],
outputs=[results_html, detail_html]
)
return app