File size: 11,375 Bytes
ccb6afe df5beb9 ccb6afe e64fb41 ccb6afe 33174dd ccb6afe d91c7bd 33174dd ccb6afe d91c7bd ccb6afe e64fb41 ccb6afe 33174dd ccb6afe d91c7bd 8881dad ccb6afe d91c7bd ccb6afe 33174dd ccb6afe e64fb41 ccb6afe e64fb41 ccb6afe d91c7bd ccb6afe e64fb41 ccb6afe 7e54de1 ccb6afe 2a1016c 3210a34 df5beb9 ccb6afe 7e54de1 ccb6afe 6c0c3bb ccb6afe d91c7bd ccb6afe |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 |
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
|