File size: 3,645 Bytes
c6bd2a2 3497525 09d067e 6d3b49f 4681e49 6d3b49f 4681e49 6d3b49f 4681e49 6d3b49f 4681e49 6d3b49f 4681e49 09d067e 6d3b49f 4681e49 6d3b49f 4681e49 09d067e 4681e49 09d067e 4681e49 09d067e 4681e49 6d3b49f 09d067e 6d3b49f e800f6d 4681e49 e800f6d 03bdc59 4681e49 03bdc59 e800f6d 4681e49 e800f6d 03bdc59 4681e49 03bdc59 4681e49 03bdc59 e800f6d 03bdc59 e800f6d |
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 |
import gradio as gr
import requests
from datetime import datetime, timezone
API_URL = "https://huggingface.co/api/daily_papers"
class PaperManager:
# ... [The PaperManager class remains unchanged] ...
css = """
body {
font-family: 'Roboto', sans-serif;
background-color: #f0f2f5;
margin: 0;
padding: 0;
}
.container {
max-width: 800px;
margin: 2rem auto;
background-color: white;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
padding: 2rem;
}
.title {
text-align: center;
color: #1a202c;
font-size: 2rem;
margin-bottom: 1.5rem;
}
.search-row {
display: flex;
gap: 1rem;
margin-bottom: 1.5rem;
align-items: flex-end;
}
.search-row > div:first-child {
flex-grow: 1;
}
.paper-list {
max-height: 500px;
overflow-y: auto;
border: 1px solid #e2e8f0;
border-radius: 8px;
padding: 1rem;
}
.paper-item {
border-bottom: 1px solid #e2e8f0;
padding: 1rem 0;
}
.paper-item:last-child {
border-bottom: none;
}
.paper-item h3 {
margin: 0 0 0.5rem 0;
}
.paper-item a {
color: #2b6cb0;
text-decoration: none;
font-weight: 600;
}
.paper-item a:hover {
text-decoration: underline;
}
.paper-meta {
font-size: 0.875rem;
color: #4a5568;
}
.footer {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 1rem;
}
button, .button {
background-color: #4299e1;
color: white;
border: none;
padding: 0.5rem 1rem;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.3s;
font-size: 0.875rem;
line-height: 1.25rem;
}
button:hover, .button:hover {
background-color: #3182ce;
}
.no-papers {
text-align: center;
color: #718096;
padding: 1rem;
}
#component-0 > div:first-child {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
#component-1 {
height: 45px;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
"""
paper_manager = PaperManager()
def initialize_app():
if paper_manager.fetch_papers():
return paper_manager.render_papers(), f"Page {paper_manager.current_page} of {paper_manager.total_pages}"
else:
return "<div class='no-papers'>Failed to fetch papers. Please try again later.</div>", "Error"
def refresh_papers():
if paper_manager.fetch_papers():
return paper_manager.render_papers(), f"Page {paper_manager.current_page} of {paper_manager.total_pages}"
else:
return "<div class='no-papers'>Failed to refresh papers. Please try again later.</div>", "Error"
demo = gr.Blocks(css=css)
with demo:
with gr.Column(elem_classes=["container"]):
gr.Markdown("# Daily Papers - HackerNews Style", elem_classes=["title"])
with gr.Row(elem_classes=["search-row"]):
search_input = gr.Textbox(label="Search papers", placeholder="Enter search term...")
refresh_button = gr.Button("Refresh", variant="primary")
paper_list = gr.HTML(elem_classes=["paper-list"])
with gr.Row(elem_classes=["footer"]):
prev_button = gr.Button("Previous Page")
page_info = gr.Markdown()
next_button = gr.Button("Next Page")
demo.load(initialize_app, outputs=[paper_list, page_info])
search_input.change(paper_manager.search_papers, inputs=[search_input], outputs=[paper_list])
refresh_button.click(refresh_papers, outputs=[paper_list, page_info])
prev_button.click(paper_manager.prev_page, outputs=[paper_list, page_info])
next_button.click(paper_manager.next_page, outputs=[paper_list, page_info])
demo.launch() |