widgets.py 3.2 KB

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