toninio19 commited on
Commit
37f4955
·
verified ·
1 Parent(s): af3b648

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +71 -88
app.py CHANGED
@@ -8,6 +8,7 @@ import pandas as pd
8
  from filelock import FileLock, Timeout
9
  from pathlib import Path
10
  import tempfile
 
11
 
12
 
13
  class VideoArenaManager:
@@ -18,6 +19,7 @@ class VideoArenaManager:
18
  self.data_file = "/data/arena_data.json" # Combined data file
19
  self.data_lock = FileLock("/data/arena_data.lock") # Single lock file
20
  self.data = self._load_data() # Load Elo ratings and results
 
21
 
22
  def _load_models(self) -> List[Dict[str, str]]:
23
  """Load available models from directories."""
@@ -89,12 +91,13 @@ class VideoArenaManager:
89
  results = {"comparisons": []}
90
  self.data = {"elo_ratings": elo_ratings, "results": results}
91
 
92
- # Update comparison results
93
  comparison = {
94
  "timestamp": datetime.now().isoformat(),
95
  "video": video_name,
96
  "winner": winner,
97
  "loser": loser,
 
98
  }
99
  self.data["results"]["comparisons"].append(comparison)
100
 
@@ -141,81 +144,92 @@ class VideoArenaManager:
141
  """Get video paths for the given pair of models."""
142
  return [os.path.join(self.base_dir, model["directory"], video_name) for model in model_pair]
143
 
 
 
 
 
144
 
145
  def create_arena_interface():
146
  manager = VideoArenaManager()
 
147
 
148
  with gr.Blocks(title="Video Model Ranking Arena") as demo:
149
- gr.Markdown(
150
- "# Video Model Ranking Arena\n\nCompare generated videos and help determine which model performs best!"
151
- )
152
 
153
- # State variables
154
- current_video = gr.State()
155
- current_models = gr.State()
156
 
157
  with gr.Row():
158
- # Display two videos side by side
159
- video_left = gr.Video(label="Model A", height=400)
160
- video_right = gr.Video(label="Model B", height=400)
161
 
162
  with gr.Row():
163
- # Buttons for voting
164
- left_button = gr.Button("👈 Left video looks better", size="lg")
165
- right_button = gr.Button("Right video looks better 👉", size="lg")
166
-
167
- # Create a Tabbed Interface
168
- with gr.Tabs():
169
- # Tab for the main video comparison interface
170
- with gr.Tab("Video Comparison"):
171
- pass # Placeholder for the comparison UI
172
-
173
- # Tab for displaying current rankings
174
- with gr.Tab("Current Rankings"):
175
- rankings_table = gr.DataFrame(
176
- manager.get_rankings(),
177
- label="Current Model Rankings",
178
- headers=["Model", "Elo Rating"],
179
- interactive=False,
180
- )
181
-
182
- def load_new_comparison():
183
- """Load a new random comparison."""
184
- video_name = random.choice(manager.videos)
185
- model_pair = manager.get_random_pair()
186
- video_paths = manager.get_video_paths(video_name, model_pair)
187
-
188
- # Update video labels
189
- video_left.label = model_pair[0]["name"]
190
- video_right.label = model_pair[1]["name"]
191
-
192
- current_video_value = video_name
193
- current_models_value = [model["name"] for model in model_pair]
194
-
195
- return (
196
- video_paths[0], # video_left
197
- video_paths[1], # video_right
198
- current_video_value, # current_video
199
- current_models_value, # current_models
200
- manager.get_rankings(), # rankings_table
201
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
202
 
203
  def handle_choice(choice_index: int, video_name: str, current_models_value: List[str]):
204
- """Handle the user's choice and update rankings."""
205
  if not current_models_value or len(current_models_value) < 2:
206
  print("Error: current_models is invalid:", current_models_value)
207
  return gr.update(visible=False), gr.update(visible=False), "", [], manager.get_rankings()
208
 
209
  winner = current_models_value[choice_index]
210
  loser = current_models_value[1 - choice_index]
211
-
212
- # Save the comparison result
213
  manager.save_comparison(video_name, winner, loser)
214
-
215
- # Load new comparison
216
  return load_new_comparison()
217
 
218
- # Button click handlers
219
  left_button.click(
220
  fn=lambda vid, models: handle_choice(0, vid, models),
221
  inputs=[current_video, current_models],
@@ -240,10 +254,10 @@ def create_arena_interface():
240
  ],
241
  )
242
 
243
- # Initial load
244
  demo.load(
245
  fn=load_new_comparison,
246
- inputs=[],
247
  outputs=[
248
  video_left,
249
  video_right,
@@ -253,37 +267,6 @@ def create_arena_interface():
253
  ],
254
  )
255
 
256
- # File management section with collapsible download option
257
- gr.Markdown("## Download Results File (Optional)")
258
-
259
- with gr.Accordion("Download Results File", open=False):
260
- files = manager.get_data_files()
261
- file_names = [file["name"] for file in files]
262
- file_select = gr.Dropdown(choices=file_names, label="Select Results File to Download", interactive=True)
263
- download_button = gr.Button("Download Selected File", size="sm") # Smaller button
264
-
265
- def download_file(file_name: str):
266
- """Prepare the selected file for download."""
267
- if not file_name:
268
- return None
269
-
270
- file_path = f"/data/{file_name}"
271
- try:
272
- # Create a temporary file to handle the download
273
- with tempfile.NamedTemporaryFile(delete=False, suffix=os.path.splitext(file_name)[1]) as tmp_file:
274
- with open(file_path, "rb") as f:
275
- tmp_file.write(f.read())
276
- return tmp_file.name
277
- except Exception as e:
278
- print(f"Error preparing download: {e}")
279
- return None
280
-
281
- download_button.click(
282
- fn=download_file,
283
- inputs=[file_select],
284
- outputs=gr.File(label="Download"),
285
- )
286
-
287
  return demo
288
 
289
 
 
8
  from filelock import FileLock, Timeout
9
  from pathlib import Path
10
  import tempfile
11
+ import uuid
12
 
13
 
14
  class VideoArenaManager:
 
19
  self.data_file = "/data/arena_data.json" # Combined data file
20
  self.data_lock = FileLock("/data/arena_data.lock") # Single lock file
21
  self.data = self._load_data() # Load Elo ratings and results
22
+ self.current_username = self.generate_random_username()
23
 
24
  def _load_models(self) -> List[Dict[str, str]]:
25
  """Load available models from directories."""
 
91
  results = {"comparisons": []}
92
  self.data = {"elo_ratings": elo_ratings, "results": results}
93
 
94
+ # Update comparison results with username
95
  comparison = {
96
  "timestamp": datetime.now().isoformat(),
97
  "video": video_name,
98
  "winner": winner,
99
  "loser": loser,
100
+ "username": self.current_username,
101
  }
102
  self.data["results"]["comparisons"].append(comparison)
103
 
 
144
  """Get video paths for the given pair of models."""
145
  return [os.path.join(self.base_dir, model["directory"], video_name) for model in model_pair]
146
 
147
+ def generate_random_username(self) -> str:
148
+ """Generate a random username."""
149
+ return f"user_{uuid.uuid4().hex[:8]}"
150
+
151
 
152
  def create_arena_interface():
153
  manager = VideoArenaManager()
154
+ ADMIN_KEY = "keyface" # Choose your secret key
155
 
156
  with gr.Blocks(title="Video Model Ranking Arena") as demo:
157
+ gr.Markdown("# Video Model Ranking Arena")
158
+ gr.Markdown("Choose which video looks better!")
 
159
 
160
+ # Add a hidden admin key input - make sure it has a unique class
161
+ with gr.Row(visible=False, elem_classes="admin-row") as admin_row:
162
+ admin_input = gr.Textbox(label="Admin Key", type="password", container=False, elem_classes="admin-input")
163
 
164
  with gr.Row():
165
+ video_left = gr.Video(label="Option A", interactive=False)
166
+ video_right = gr.Video(label="Option B", interactive=False)
 
167
 
168
  with gr.Row():
169
+ left_button = gr.Button("Choose Left (A)", size="lg")
170
+ right_button = gr.Button("Choose Right (B)", size="lg")
171
+
172
+ # Hidden state management
173
+ current_video = gr.State("")
174
+ current_models = gr.State([])
175
+
176
+ # Rankings display
177
+ rankings_table = gr.Dataframe(
178
+ headers=["Model", "Rating"],
179
+ label="Current Rankings",
180
+ )
181
+
182
+ # Add this CSS and JS to handle the admin functionality
183
+ demo.load(
184
+ None,
185
+ None,
186
+ _js="""
187
+ function() {
188
+ // Hide download button by default
189
+ const downloadBtn = document.querySelector('.download-button');
190
+ if (downloadBtn) {
191
+ downloadBtn.style.setProperty('display', 'none', 'important');
192
+ }
193
+
194
+ // Add keyboard shortcut listener for admin panel
195
+ document.addEventListener('keydown', function(e) {
196
+ // Check for Ctrl+Shift+K
197
+ if (e.ctrlKey && e.shiftKey && e.key === 'K') {
198
+ const adminRow = document.querySelector('.admin-row');
199
+ if (adminRow) {
200
+ adminRow.style.display = adminRow.style.display === 'none' ? 'block' : 'none';
201
+ }
202
+ }
203
+ });
204
+
205
+ // Add input listener for admin key
206
+ const adminInput = document.querySelector('.admin-input input');
207
+ if (adminInput) {
208
+ adminInput.addEventListener('input', function(e) {
209
+ const downloadBtn = document.querySelector('.download-button');
210
+ if (downloadBtn) {
211
+ if (e.target.value === 'your_secret_key_here') {
212
+ downloadBtn.style.setProperty('display', 'block', 'important');
213
+ } else {
214
+ downloadBtn.style.setProperty('display', 'none', 'important');
215
+ }
216
+ }
217
+ });
218
+ }
219
+ }
220
+ """.replace("your_secret_key_here", ADMIN_KEY),
221
+ ) # Inject the admin key securely
222
 
223
  def handle_choice(choice_index: int, video_name: str, current_models_value: List[str]):
 
224
  if not current_models_value or len(current_models_value) < 2:
225
  print("Error: current_models is invalid:", current_models_value)
226
  return gr.update(visible=False), gr.update(visible=False), "", [], manager.get_rankings()
227
 
228
  winner = current_models_value[choice_index]
229
  loser = current_models_value[1 - choice_index]
 
 
230
  manager.save_comparison(video_name, winner, loser)
 
 
231
  return load_new_comparison()
232
 
 
233
  left_button.click(
234
  fn=lambda vid, models: handle_choice(0, vid, models),
235
  inputs=[current_video, current_models],
 
254
  ],
255
  )
256
 
257
+ # Load initial comparison
258
  demo.load(
259
  fn=load_new_comparison,
260
+ inputs=None,
261
  outputs=[
262
  video_left,
263
  video_right,
 
267
  ],
268
  )
269
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
270
  return demo
271
 
272