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: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; background-color: #f0f2f5; margin: 0; padding: 0; } .container { max-width: 100%; margin: 0 auto; background-color: white; padding: 1rem; box-sizing: border-box; display: flex; flex-direction: column; min-height: 100vh; } .title { text-align: center; color: #1a202c; font-size: 1.5rem; margin-bottom: 1rem; } .search-row { display: flex; gap: 0.5rem; margin-bottom: 1rem; align-items: flex-end; } .search-row > div:first-child { flex-grow: 1; } .paper-list { flex-grow: 1; overflow-y: auto; border: 1px solid #e2e8f0; border-radius: 8px; padding: 0.5rem; margin-bottom: 1rem; } .paper-item { border-bottom: 1px solid #e2e8f0; padding: 0.5rem 0; } .paper-item:last-child { border-bottom: none; } .paper-item h3 { margin: 0 0 0.25rem 0; font-size: 1rem; } .paper-item a { color: #2b6cb0; text-decoration: none; font-weight: 600; } .paper-item a:hover { text-decoration: underline; } .paper-meta { font-size: 0.75rem; color: #4a5568; display: flex; flex-wrap: wrap; gap: 0.5rem; } .footer { display: flex; justify-content: space-between; align-items: center; padding-top: 0.5rem; } button, .button { background-color: #4299e1; color: white; border: none; padding: 0.25rem 0.5rem; 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; } @media (min-width: 640px) { .container { max-width: 640px; padding: 1.5rem; } .title { font-size: 1.75rem; } .paper-item h3 { font-size: 1.125rem; } .paper-meta { font-size: 0.875rem; } } @media (min-width: 768px) { .container { max-width: 768px; } } """ 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 "
Failed to fetch papers. Please try again later.
", "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 "
Failed to refresh papers. Please try again later.
", "Error" demo = gr.Blocks(css=css) with demo: with gr.Column(elem_classes=["container"]): gr.Markdown("# Daily Papers", elem_classes=["title"]) with gr.Row(elem_classes=["search-row"]): search_input = gr.Textbox(label="", placeholder="Search papers...") refresh_button = gr.Button("↻", variant="primary") paper_list = gr.HTML(elem_classes=["paper-list"]) with gr.Row(elem_classes=["footer"]): prev_button = gr.Button("← Prev") page_info = gr.Markdown() next_button = gr.Button("Next →") 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()