Juggling commited on
Commit
f4a355a
·
verified ·
1 Parent(s): d5f07f2

Updated markdown text about generating schedules

Browse files
Files changed (1) hide show
  1. main.py +73 -11
main.py CHANGED
@@ -41,8 +41,11 @@ theme = gr.themes.Soft(
41
  )
42
 
43
  ### Connect to Supabase ###
44
- URL = os.environ['URL']
45
- API_KEY = os.environ['API_KEY']
 
 
 
46
  client = supabase.create_client(URL, API_KEY)
47
 
48
 
@@ -82,7 +85,7 @@ def make_form(email: str, schedule_name: str, password_1: str, password_2: str,
82
  return gr.Warning('', ALERT_TIME, title=f"The capacity (number of people who can teach per timeslot) must be greater than zero.")
83
 
84
  if len(slots) == 0:
85
- return gr.Warning('', ALERT_TIME, title="Please enter at least one timeslot. Make sure to press \"Enter\" after each one!")
86
 
87
 
88
  # Check if schedule name already exists
@@ -178,7 +181,7 @@ def submit_preferences(schedule_name: str, curr_juggler_name: str, curr_email: s
178
  return gr.Warning('', ALERT_TIME, title=f"You only selected {len(curr_availability)} timeslots. However, you said you wanted to teach {curr_num_workshops} workshops. Please make sure that you are available to teach during at least {curr_num_workshops} timeslots.")
179
 
180
  if len(curr_descriptions) == 0:
181
- return gr.Warning('', ALERT_TIME, title=f"Please describe at least one workshop that you want to teach. You must hit \"Enter\" after each one!")
182
 
183
  response = client.table('Forms').select('responses', 'slots').eq('form_name', standardize(schedule_name)).execute()
184
  data = response.data
@@ -252,7 +255,7 @@ Returns:
252
  gr.Button: corresponds to open_close_btn
253
  '''
254
  def make_visible(schedule_name:str, password: str):
255
- skip_output = gr.Button(), gr.Column(), gr.Column(), gr.Row(), gr.Column(), gr.Button()
256
 
257
  if len(schedule_name) == 0:
258
  gr.Warning('Please enter the form name.', ALERT_TIME)
@@ -273,11 +276,11 @@ def make_visible(schedule_name:str, password: str):
273
  else:
274
  if my_dict['status'] == 'open':
275
  gr.Info('', ALERT_TIME, title='Btw, the form is currently OPEN.')
276
- return gr.Button(variant='secondary'), gr.Column(visible=True), gr.Column(visible=True), gr.Row(visible=True), gr.Column(visible=True), gr.Button("Close Form", visible=True)
277
 
278
  elif my_dict['status'] == 'closed':
279
  gr.Info('', ALERT_TIME, title='Btw, the form is currently CLOSED.')
280
- return gr.Button(variant='secondary'), gr.Column(visible=True), gr.Column(visible=True), gr.Row(visible=True),gr.Column(visible=True), gr.Button("Open Form", visible=True)
281
 
282
  else:
283
  gr.Warning(f"There is no form called \"{schedule_name}\". Please check the spelling and try again.", ALERT_TIME)
@@ -417,10 +420,60 @@ def toggle_btn(schedule_name:str, password:str):
417
  return gr.Button()
418
 
419
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
420
  ### MARKDOWN TEXT ###
421
  generate_markdown = f"""
422
- The app will attempt to create schedules where everyone is teaching their descired number of workshops AND all timeslots are filled.\n
423
  If that is impossible, then the app will create schedules that maximize the number of timeslots that are filled.\n
 
424
  You can either get a random selection of the best schedules (recommended), or ALL of the best schedules.\n
425
  WARNING: It can sometimes take a LONG time to get all the best schedules!
426
  """
@@ -461,7 +514,7 @@ with gr.Blocks() as demo:
461
 
462
  # Let the user dynamically describe their workshops
463
  descriptions = gr.State([])
464
- new_description = gr.Textbox(label='Workshop Descriptions', info='Describe the workshop(s) you want to teach. Include the title, prereqs, and difficulty level for each workshop. Hit "Enter" after each one.', visible=False)
465
 
466
  def add_descrip(descriptions, new_description):
467
  return descriptions + [{"name": new_description}], ""
@@ -496,7 +549,7 @@ with gr.Blocks() as demo:
496
  # Dynamically render timeslots
497
  # Based on: https://www.gradio.app/guides/dynamic-apps-with-render-decorator
498
  slots = gr.State([])
499
- new_slot = gr.Textbox(label='Enter Timeslots People Can Teach', info='Ex: Friday 7 pm, Saturday 11 am. Hit "Enter" after each one. Make sure to put them in CHRONOLOGICAL ORDER!')
500
 
501
  def add_slot(slots, new_slot_name):
502
  return slots + [{"name": new_slot_name}], ""
@@ -568,7 +621,16 @@ with gr.Blocks() as demo:
568
  open_close_btn.click(fn=toggle_btn, inputs=[schedule_name, password], outputs=[open_close_btn])
569
 
570
 
571
- find_form_btn.click(fn=make_visible, inputs=[schedule_name, password], outputs=[find_form_btn, all_responses_col, generate_schedules_explanation_col, generate_btns_row, open_close_btn_col, open_close_btn])
 
 
 
 
 
 
 
 
 
572
 
573
 
574
  ### INFO ###
 
41
  )
42
 
43
  ### Connect to Supabase ###
44
+ #URL = os.environ['URL']
45
+ #API_KEY = os.environ['API_KEY']
46
+ # TODO
47
+ URL = 'https://ubngctgvhjgxkvimdmri.supabase.co'
48
+ API_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InVibmdjdGd2aGpneGt2aW1kbXJpIiwicm9sZSI6ImFub24iLCJpYXQiOjE3MzQ5MjAwOTQsImV4cCI6MjA1MDQ5NjA5NH0.NtGdfP8GYNuYdPdsaLW5GjgfB0_7Q1kNBIDJtPhO8nY'
49
  client = supabase.create_client(URL, API_KEY)
50
 
51
 
 
85
  return gr.Warning('', ALERT_TIME, title=f"The capacity (number of people who can teach per timeslot) must be greater than zero.")
86
 
87
  if len(slots) == 0:
88
+ return gr.Warning('', ALERT_TIME, title="Please enter at least one timeslot. Make sure to press \"Enter\" after each one (\"Return\" if you're on mobile)!")
89
 
90
 
91
  # Check if schedule name already exists
 
181
  return gr.Warning('', ALERT_TIME, title=f"You only selected {len(curr_availability)} timeslots. However, you said you wanted to teach {curr_num_workshops} workshops. Please make sure that you are available to teach during at least {curr_num_workshops} timeslots.")
182
 
183
  if len(curr_descriptions) == 0:
184
+ return gr.Warning('', ALERT_TIME, title=f"Please describe at least one workshop that you want to teach. You must hit \"Enter\" after each one (\"Return\" if you're on mobile)!")
185
 
186
  response = client.table('Forms').select('responses', 'slots').eq('form_name', standardize(schedule_name)).execute()
187
  data = response.data
 
255
  gr.Button: corresponds to open_close_btn
256
  '''
257
  def make_visible(schedule_name:str, password: str):
258
+ skip_output = gr.Button(), gr.Column(), gr.Column(), gr.Row(), gr.Column(), gr.Button(), gr.Column
259
 
260
  if len(schedule_name) == 0:
261
  gr.Warning('Please enter the form name.', ALERT_TIME)
 
276
  else:
277
  if my_dict['status'] == 'open':
278
  gr.Info('', ALERT_TIME, title='Btw, the form is currently OPEN.')
279
+ return gr.Button(variant='secondary'), gr.Column(visible=True), gr.Column(visible=True), gr.Row(visible=True), gr.Column(visible=True), gr.Button("Close Form", visible=True), gr.Column(visible=True)
280
 
281
  elif my_dict['status'] == 'closed':
282
  gr.Info('', ALERT_TIME, title='Btw, the form is currently CLOSED.')
283
+ return gr.Button(variant='secondary'), gr.Column(visible=True), gr.Column(visible=True), gr.Row(visible=True),gr.Column(visible=True), gr.Button("Open Form", visible=True), gr.Column(visible=True)
284
 
285
  else:
286
  gr.Warning(f"There is no form called \"{schedule_name}\". Please check the spelling and try again.", ALERT_TIME)
 
420
  return gr.Button()
421
 
422
 
423
+ '''
424
+ Delete a response
425
+ Returns: None
426
+ '''
427
+ def my_delete(schedule_name: str, curr_juggler_name: str):
428
+ response = client.table('Forms').select('responses', 'slots').eq('form_name', standardize(schedule_name)).execute()
429
+ data = response.data
430
+
431
+ if len(data) > 0:
432
+ form = json.loads(data[0]['responses'])
433
+
434
+ # Get current lists
435
+ curr_juggler_name = curr_juggler_name.strip()
436
+ names = form[NAME_COL]
437
+ emails = form[EMAIL_COL]
438
+ bandwidths = form[NUM_WORKSHOPS_COL]
439
+ availabilities = form[AVAIL_COL]
440
+ descriptions = form[DESCRIP_COL]
441
+
442
+ # Get index of the juggler's name
443
+ try:
444
+ index = names.index(curr_juggler_name)
445
+ except:
446
+ return gr.Warning('', ALERT_TIME, title=f"\"{curr_juggler_name}\" is not in the form responses. Please check the spelling and try again.")
447
+
448
+ # Remove juggler's responses from the lists
449
+ del names[index]
450
+ del emails[index]
451
+ del bandwidths[index]
452
+ del availabilities[index]
453
+ del descriptions[index]
454
+
455
+ # Update Supabase
456
+ my_obj = json.dumps({
457
+ NAME_COL: names,
458
+ EMAIL_COL: emails,
459
+ NUM_WORKSHOPS_COL: bandwidths,
460
+ AVAIL_COL: availabilities,
461
+ DESCRIP_COL: descriptions
462
+ })
463
+ client.table('Forms').update({'responses': my_obj}).eq('form_name', standardize(schedule_name)).execute()
464
+ return gr.Info('', ALERT_TIME, title='Response deleted successfully!')
465
+
466
+ # I don't think it's possible to get here because I checked the schedule name earlier
467
+ else:
468
+ return gr.Warning('', ALERT_TIME, title=f"There was no form called \"{schedule_name}\". Please check the spelling and try again.")
469
+
470
+
471
+
472
  ### MARKDOWN TEXT ###
473
  generate_markdown = f"""
474
+ The app will attempt to create schedules where everyone is teaching their desired number of workshops AND all timeslots are filled.\n
475
  If that is impossible, then the app will create schedules that maximize the number of timeslots that are filled.\n
476
+ If someone can teach at every possible timeslot, then they willl NOT be in any of the schedules (this helps the code run faster).\n
477
  You can either get a random selection of the best schedules (recommended), or ALL of the best schedules.\n
478
  WARNING: It can sometimes take a LONG time to get all the best schedules!
479
  """
 
514
 
515
  # Let the user dynamically describe their workshops
516
  descriptions = gr.State([])
517
+ new_description = gr.Textbox(label='Workshop Descriptions', info='Describe the workshop(s) you want to teach. Include the title, prereqs, and difficulty level for each workshop. Hit "Enter" after each one ("Return" if you\'re on mobile).', visible=False)
518
 
519
  def add_descrip(descriptions, new_description):
520
  return descriptions + [{"name": new_description}], ""
 
549
  # Dynamically render timeslots
550
  # Based on: https://www.gradio.app/guides/dynamic-apps-with-render-decorator
551
  slots = gr.State([])
552
+ new_slot = gr.Textbox(label='Enter Timeslots People Can Teach', info='Ex: Friday 7 pm, Saturday 11 am. Hit "Enter" after each one ("Return" if you\'re on mobile). Make sure to put them in CHRONOLOGICAL ORDER!')
553
 
554
  def add_slot(slots, new_slot_name):
555
  return slots + [{"name": new_slot_name}], ""
 
621
  open_close_btn.click(fn=toggle_btn, inputs=[schedule_name, password], outputs=[open_close_btn])
622
 
623
 
624
+ # 4. Delete response
625
+ with gr.Column(visible=False) as delete_btn_col:
626
+ gr.Markdown('# Delete a Response')
627
+ gr.Markdown('Pressing this button will delete the juggler\'s response entirely. Warning: this CANNOT be undone!!')
628
+ juggler_name = gr.Textbox(label="Juggler's Name: Enter the name of the juggler's response that you want to delete")
629
+ delete_btn = gr.Button('Delete Response')
630
+ delete_btn.click(fn=my_delete, inputs=[schedule_name, juggler_name])
631
+
632
+
633
+ find_form_btn.click(fn=make_visible, inputs=[schedule_name, password], outputs=[find_form_btn, all_responses_col, generate_schedules_explanation_col, generate_btns_row, open_close_btn_col, open_close_btn, delete_btn_col])
634
 
635
 
636
  ### INFO ###