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"{author.name}"
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"
{article.title or 'Untitled Paper'}
")
info.append(f"")
info.append(f"Hugging Face{assets.SVG_LINK}")
info.append(f"arXiv{assets.SVG_LINK}")
info.append(f"PDF{assets.SVG_LINK}")
info.append(f"
")
# Thumbnail
if article.thumbnail:
info.append(f"![]({article.thumbnail})
")
# Basic information
info.append(
f"Paper ID: {article.paper.id or 'Unknown'}
")
info.append(
f"Published At: {article.paper.publishedAt.strftime('%Y-%m-%d %H:%M') if article.paper.publishedAt else 'Unknown'}
")
# 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"Authors: {authors}
")
# Summary
if article.paper.summary:
summary = article.paper.summary.replace('{{', '{').replace('}}', '}').replace('\n', ' ')
info.append(f"Summary
{summary}
")
# Discussion information
info.append(f"Upvotes: {article.paper.upvotes or 0}")
info.append(f"Comments: {article.numComments or 0}
")
if article.paper.discussionId:
info.append(
f"Join Discussion{assets.SVG_LINK}")
# Submitter information
if article.submittedBy:
submitter = article.submittedBy
info.append(f"
Submitter: ")
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"
{submitter.fullname}(@{submitter.name}) ")
info.append(f"Followers: {submitter.followerCount or 0}
")
return "".join(info)
def generate_table_html(papers):
"""Generate table HTML with clickable titles and an extra column for arXiv abs link"""
html = [''
'Title | '
'👍 Upvotes | '
'💬 Comments | '
'📅 Date | '
# 'Label | '
' | '
'
']
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"""
{title}{assets.SVG_LINK} |
{upvotes} |
{comments} |
{date} |
Details{assets.SVG_LINK} |
""" # {label} |
html.append(row)
html.append("
")
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"{article_html}
"
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 "⚠️ Query failed, please check the date format (YYYY-MM-DD)
", "⚠️ Query failed, please check the date format (YYYY-MM-DD)
"
# 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"") as app:
# Main interface
gr.HTML("📚 Hugging Face Weekly Paper
")
gr.HTML("""""")
# 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