IAMJB commited on
Commit
741c163
·
1 Parent(s): 4884e18
Files changed (4) hide show
  1. app.py +44 -4
  2. df/PaperCentral.py +2 -2
  3. pr_paper_central_tab.py +165 -0
  4. style.css +34 -9
app.py CHANGED
@@ -2,20 +2,55 @@ import gradio as gr
2
  from df.PaperCentral import PaperCentral
3
  from gradio_calendar import Calendar
4
  from datetime import datetime, timedelta
5
- from typing import Union, List, Optional
6
  from author_leaderboard_tab import author_leaderboard_tab
 
 
 
 
7
  from author_leaderboard_contrib_tab import author_resource_leaderboard_tab
8
  from zoneinfo import ZoneInfo # Available in Python 3.9 and later
9
 
10
  # Initialize the PaperCentral class instance
11
  paper_central_df = PaperCentral()
12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  # Create the Gradio Blocks app with custom CSS
14
  with gr.Blocks(css="style.css") as demo:
15
  gr.Markdown("# Paper Central")
16
-
17
- with gr.Tabs() as tabs:
18
- with gr.Tab("Paper-central", id="tab-paper-central"):
 
 
19
  with gr.Accordion(label="⭐Release notes", open=False):
20
  gr.Markdown("""
21
  - **October 16, 2024** – Added functionality to filter papers by date ranges.
@@ -25,6 +60,8 @@ with gr.Blocks(css="style.css") as demo:
25
  - **October 4, 2024** – Added functionality to filter papers by title.
26
  """)
27
 
 
 
28
  # Create a row for navigation buttons and calendar
29
  with gr.Row():
30
  with gr.Column(scale=1):
@@ -119,6 +156,9 @@ with gr.Blocks(css="style.css") as demo:
119
  wrap=True,
120
  )
121
 
 
 
 
122
  with gr.Tab("Leaderboards", id="tab-leaderboards"):
123
  with gr.Tab("Authors"):
124
  author_leaderboard_tab()
 
2
  from df.PaperCentral import PaperCentral
3
  from gradio_calendar import Calendar
4
  from datetime import datetime, timedelta
5
+ from typing import Union, List, Optional, Tuple
6
  from author_leaderboard_tab import author_leaderboard_tab
7
+ from pr_paper_central_tab import pr_paper_central_tab
8
+ from huggingface_hub import whoami
9
+ import json
10
+
11
  from author_leaderboard_contrib_tab import author_resource_leaderboard_tab
12
  from zoneinfo import ZoneInfo # Available in Python 3.9 and later
13
 
14
  # Initialize the PaperCentral class instance
15
  paper_central_df = PaperCentral()
16
 
17
+
18
+ def hide_if_logged_in(oauth_token: Optional[gr.OAuthToken]):
19
+ if oauth_token is None:
20
+ return gr.update(visible=True)
21
+ return gr.update(visible=False)
22
+
23
+
24
+ def display_user_info(oauth_token: Optional[gr.OAuthToken]):
25
+ if oauth_token is None:
26
+ return ""
27
+ user_info = whoami(oauth_token.token)
28
+ avatar_url = user_info.get("avatarUrl", "")
29
+ fullname = user_info.get("fullname", "")
30
+ name = user_info.get("name", "")
31
+
32
+ # Prepare the custom HTML for the avatar
33
+ avatar_html = \
34
+ f'''
35
+ <div style="display: flex; align-items: center;">
36
+ <img alt="Avatar" src="{avatar_url}"
37
+ style="border: 2px solid rgb(245, 158, 11); border-radius: 50%; width: 1.38rem; height: 1.38rem; margin-right: 0.5rem;">
38
+ <span style="font-size: 1rem;">{name}</span>
39
+ </div>
40
+ Head to "PR paper-central" tab to modify your paper!
41
+ '''
42
+
43
+ return gr.update(value=avatar_html, label="User")
44
+
45
+
46
  # Create the Gradio Blocks app with custom CSS
47
  with gr.Blocks(css="style.css") as demo:
48
  gr.Markdown("# Paper Central")
49
+ with gr.Row():
50
+ with gr.Column(scale=1):
51
+ gr.LoginButton(value="PR this space").attach_load_event(hide_if_logged_in, None)
52
+ user_info_md = gr.HTML().attach_load_event(display_user_info, None)
53
+ with gr.Column(scale=1):
54
  with gr.Accordion(label="⭐Release notes", open=False):
55
  gr.Markdown("""
56
  - **October 16, 2024** – Added functionality to filter papers by date ranges.
 
60
  - **October 4, 2024** – Added functionality to filter papers by title.
61
  """)
62
 
63
+ with gr.Tabs() as tabs:
64
+ with gr.Tab("Paper-central", id="tab-paper-central"):
65
  # Create a row for navigation buttons and calendar
66
  with gr.Row():
67
  with gr.Column(scale=1):
 
156
  wrap=True,
157
  )
158
 
159
+ with gr.Tab("PR paper-central", id="tab-pr"):
160
+ pr_paper_central_tab(paper_central_df.df_raw)
161
+
162
  with gr.Tab("Leaderboards", id="tab-leaderboards"):
163
  with gr.Tab("Authors"):
164
  author_leaderboard_tab()
df/PaperCentral.py CHANGED
@@ -425,12 +425,12 @@ class PaperCentral:
425
  if 'id' not in columns_to_show:
426
  columns_to_show.append('id')
427
 
428
- if "In proceedings" in conference_options:
429
  filtered_df = filtered_df[
430
  filtered_df['conference_name'].notna() & (filtered_df['conference_name'] != "")
431
  ]
432
 
433
- other_conferences = [conf for conf in conference_options if conf != "In proceedings"]
434
  if other_conferences:
435
  conference_filter = pd.Series(False, index=filtered_df.index)
436
  for conference in other_conferences:
 
425
  if 'id' not in columns_to_show:
426
  columns_to_show.append('id')
427
 
428
+ if "ALL" in conference_options:
429
  filtered_df = filtered_df[
430
  filtered_df['conference_name'].notna() & (filtered_df['conference_name'] != "")
431
  ]
432
 
433
+ other_conferences = [conf for conf in conference_options if conf != "ALL"]
434
  if other_conferences:
435
  conference_filter = pd.Series(False, index=filtered_df.index)
436
  for conference in other_conferences:
pr_paper_central_tab.py ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from typing import Optional
3
+ import pandas as pd
4
+ from huggingface_hub import HfApi, hf_hub_download, CommitOperationAdd
5
+ import json
6
+ import os
7
+
8
+
9
+ # PR function as before
10
+ def create_pr_in_hf_dataset(new_entry, oauth_token: gr.OAuthToken):
11
+ # Dataset and filename
12
+ REPO_ID = 'IAMJB/paper-central-pr'
13
+ FILENAME = 'data.json'
14
+
15
+ # Initialize HfApi
16
+ api = HfApi()
17
+ token = oauth_token.token
18
+
19
+ # Ensure the repository exists and has an initial empty data.json if not present
20
+ try:
21
+ # Create the repository if it doesn't exist
22
+ api.create_repo(repo_id=REPO_ID, token=token, repo_type='dataset', exist_ok=True)
23
+
24
+ # Check if data.json exists; if not, create it with empty list
25
+ files = api.list_repo_files(REPO_ID, repo_type='dataset', token=token)
26
+ if FILENAME not in files:
27
+ # Initialize with empty list
28
+ empty_data = []
29
+ temp_filename = 'temp_data.json'
30
+ with open(temp_filename, 'w') as f:
31
+ json.dump(empty_data, f)
32
+ commit = CommitOperationAdd(path_in_repo=FILENAME, path_or_fileobj=temp_filename)
33
+ api.create_commit(
34
+ repo_id=REPO_ID,
35
+ operations=[commit],
36
+ commit_message="Initialize data.json",
37
+ repo_type="dataset",
38
+ token=token,
39
+ )
40
+ os.remove(temp_filename)
41
+ except Exception as e:
42
+ return f"Error creating or accessing repository: {e}"
43
+
44
+ # Download existing data from the dataset
45
+ try:
46
+ # Download the existing data.json file
47
+ local_filepath = hf_hub_download(repo_id=REPO_ID, filename=FILENAME, repo_type='dataset', token=token)
48
+ with open(local_filepath, 'r') as f:
49
+ data = json.load(f)
50
+ except Exception as e:
51
+ print(f"Error downloading existing data: {e}")
52
+ data = []
53
+
54
+ # Add the new entry
55
+ data.append(new_entry)
56
+
57
+ # Save to temporary file
58
+ temp_filename = 'temp_data.json'
59
+ with open(temp_filename, 'w') as f:
60
+ json.dump(data, f, indent=2)
61
+
62
+ # Create commit operation
63
+ commit = CommitOperationAdd(path_in_repo=FILENAME, path_or_fileobj=temp_filename)
64
+
65
+ # Create PR
66
+ try:
67
+ res = api.create_commit(
68
+ repo_id=REPO_ID,
69
+ operations=[commit],
70
+ commit_message=f"Add new entry for arXiv ID {new_entry['arxiv_id']}",
71
+ repo_type="dataset",
72
+ create_pr=True,
73
+ token=token,
74
+ )
75
+ pr_url = res.pr_url
76
+ os.remove(temp_filename)
77
+ except Exception as e:
78
+ print(f"Error creating PR: {e}")
79
+ pr_url = "Error creating PR."
80
+
81
+ return pr_url
82
+
83
+
84
+ def pr_paper_central_tab(paper_central_df):
85
+ with gr.Column():
86
+ gr.Markdown("## PR Paper-central")
87
+
88
+ # Message to prompt user to log in
89
+ login_prompt = gr.Markdown("Please log in to proceed.", visible=False)
90
+
91
+ # Input for arXiv ID
92
+ arxiv_id_input = gr.Textbox(label="Enter arXiv ID")
93
+ arxiv_id_button = gr.Button("Submit")
94
+
95
+ # Message to display errors or information
96
+ message = gr.Markdown("", visible=False)
97
+
98
+ # Define the fields dynamically
99
+ fields = [
100
+ {'name': 'paper_page', 'label': 'Paper Page'},
101
+ {'name': 'github', 'label': 'GitHub URL'},
102
+ {'name': 'conference_name', 'label': 'Conference Name'},
103
+ {'name': 'type_', 'label': 'Type'}, # Renamed from 'type' to 'type_'
104
+ {'name': 'proceedings', 'label': 'Proceedings'},
105
+ # Add or remove fields here as needed
106
+ ]
107
+
108
+ input_fields = {}
109
+ for field in fields:
110
+ input_fields[field['name']] = gr.Textbox(label=field['label'], visible=False)
111
+
112
+ # Button to create PR
113
+ create_pr_button = gr.Button("Create PR", visible=False)
114
+
115
+ # Output message
116
+ pr_message = gr.Markdown("", visible=False)
117
+
118
+ # Function to handle arxiv_id submission and check login
119
+ def check_login_and_handle_arxiv_id(arxiv_id, oauth_token: Optional[gr.OAuthToken]):
120
+ if oauth_token is None:
121
+ return [gr.update(value="Please log in to proceed.", visible=True)] + \
122
+ [gr.update(visible=False) for _ in fields] + \
123
+ [gr.update(visible=False)] # create_pr_button
124
+ else:
125
+ if arxiv_id not in paper_central_df['arxiv_id'].values:
126
+ return [gr.update(value="arXiv ID not found. Please try again.", visible=True)] + \
127
+ [gr.update(visible=False) for _ in fields] + [gr.update(visible=False)] # create_pr_button
128
+ else:
129
+ row = paper_central_df[paper_central_df['arxiv_id'] == arxiv_id].iloc[0]
130
+ updates = [gr.update(value="", visible=False)] # message
131
+ for field in fields:
132
+ value = row.get(field['name'], "")
133
+ updates.append(gr.update(value=value, visible=True))
134
+ updates.append(gr.update(visible=True)) # create_pr_button
135
+ return updates
136
+
137
+ arxiv_id_button.click(
138
+ fn=check_login_and_handle_arxiv_id,
139
+ inputs=[arxiv_id_input],
140
+ outputs=[message] + [input_fields[field['name']] for field in fields] + [create_pr_button]
141
+ )
142
+
143
+ # Function to create PR
144
+ def create_pr(message, arxiv_id, paper_page, github, conference_name, type_, proceedings,
145
+ oauth_token: Optional[gr.OAuthToken] = None):
146
+ if oauth_token is None:
147
+ return gr.update(value="Please log in first.", visible=True)
148
+ else:
149
+ new_entry = {
150
+ 'arxiv_id': arxiv_id,
151
+ 'paper_page': paper_page,
152
+ 'github': github,
153
+ 'conference_name': conference_name,
154
+ 'type': type_,
155
+ 'proceedings': proceedings
156
+ }
157
+ # Now add this to the dataset and create a PR
158
+ pr_url = create_pr_in_hf_dataset(new_entry, oauth_token)
159
+ return gr.update(value=f"PR created: {pr_url}", visible=True)
160
+
161
+ create_pr_button.click(
162
+ fn=create_pr,
163
+ inputs=[pr_message, arxiv_id_input] + [input_fields[field['name']] for field in fields],
164
+ outputs=[pr_message]
165
+ )
style.css CHANGED
@@ -21,15 +21,40 @@ body a:hover {
21
  }
22
 
23
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
 
25
- #hf_options label[for='github']::before {
26
- content: "";
27
- background-image: url('https://github.githubassets.com/favicons/favicon.png');
28
- background-size: contain;
29
- display: inline-block;
30
- width: 16px;
31
- height: 16px;
32
- vertical-align: middle;
33
- margin-right: 5px;
34
  }
35
 
 
 
 
 
 
 
 
21
  }
22
 
23
 
24
+ #login-row {
25
+ justify-content: center;
26
+ display: flex;
27
+ }
28
+
29
+
30
+
31
+
32
+ .avatar-container {
33
+ position: relative;
34
+ margin-left: 0.5rem;
35
+ width: 1.38rem;
36
+ height: 1.38rem;
37
+ }
38
+
39
+ .avatar-button {
40
+ margin-left: auto;
41
+ border-radius: 9999px;
42
+ ring: 2px solid rgb(245 158 11);
43
+ outline: 2px solid transparent;
44
+ outline-offset: 2px;
45
+ background: none;
46
+ border: none;
47
+ padding: 0;
48
+ cursor: pointer;
49
+ }
50
 
51
+ .avatar-button:hover {
52
+ ring-offset: 1px;
 
 
 
 
 
 
 
53
  }
54
 
55
+ .avatar-image {
56
+ width: 1.38rem;
57
+ height: 1.38rem;
58
+ overflow: hidden;
59
+ border-radius: 9999px;
60
+ }