widgets.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. import datetime
  2. import ctypes
  3. from django.forms.widgets import Widget
  4. from .models import Participant, Date, Event
  5. from .helpers import string2slots, get_slot_count, slots2string, slots2grid
  6. class DatePickerWidget(Widget):
  7. template_name = 'widgets/date-picker.html'
  8. n_weeks = 5
  9. def get_context(self, name, value, attrs):
  10. context = super().get_context(name, value, attrs)
  11. # get first day of the week
  12. today = datetime.date.today()
  13. context['widget']['today'] = today
  14. first_day_of_week = today - datetime.timedelta(days=today.weekday())
  15. # get the weekdays
  16. weekdays = []
  17. for i in range(7):
  18. weekdays.append((first_day_of_week + datetime.timedelta(days=i)).strftime('%A')[0])
  19. context['widget']['weekdays'] = weekdays
  20. # for the next weeks
  21. weeks = []
  22. for i in range(self.n_weeks):
  23. date = first_day_of_week + datetime.timedelta(days=i*7)
  24. week = {
  25. 'days': [],
  26. 'month': date.strftime('%b'),
  27. 'year': date.strftime('%Y'),
  28. }
  29. for j in range(7):
  30. day = {
  31. 'date': date + datetime.timedelta(days=j),
  32. 'day': (date + datetime.timedelta(days=j)).strftime('%d'),
  33. }
  34. week['days'].append(day)
  35. weeks.append(week)
  36. context['widget']['weeks'] = weeks
  37. return context
  38. def value_from_datadict(self, data, files, name):
  39. dates = []
  40. for day in self.GetValidDates():
  41. if data.get(f"date_{day.strftime('%Y-%m-%d')}") == "on":
  42. dates.append(day)
  43. return dates
  44. def value_omitted_from_data(self, data, files, name):
  45. return not any(
  46. (data.get(f"date_{day.strftime('%Y-%m-%d')}") == "on")
  47. for day in self.GetValidDates()
  48. )
  49. def GetValidDates(self):
  50. today = datetime.date.today()
  51. return [
  52. (today + datetime.timedelta(days=i))
  53. for i in range(7*self.n_weeks)
  54. ]
  55. class SlotPickerWidget(Widget):
  56. template_name = 'widgets/slot-picker.html'
  57. def get_context(self, name, value, attrs):
  58. context = super().get_context(name, value, attrs)
  59. event: Event = self.participant.event
  60. context['widget']['grid'] = slots2grid(event, [self.participant])
  61. return context
  62. def value_from_datadict(self, data, files, name):
  63. # create a mutable string buffer
  64. slots = ctypes.create_string_buffer(self.n_slots)
  65. # set the slots
  66. for i in range(self.n_slots):
  67. if data.get(f"slot_{i}") == "on":
  68. slots[i] = b'1'
  69. else:
  70. slots[i] = b'0'
  71. # return the slots as a string
  72. return slots.value
  73. def value_omitted_from_data(self, data, files, name):
  74. return False
  75. def __init__(self, *args, participant, **kwargs):
  76. super().__init__(*args, **kwargs)
  77. self.participant = participant
  78. self.n_slots = get_slot_count(participant.event)