import datetime from .models import Participant, Date, Event def slots2string( participant : Participant, n_slots : int ) -> str : """ Convert the slots of a participant to a string. """ # Get the slots of the participant byte_array = participant.slots # Convert the slots to a string string_value = bin(int.from_bytes(byte_array, byteorder='big'))[2:] # Pad the string with 0s if necessary return '0' * (n_slots - len(string_value)) + string_value def string2slots( string : str ) -> bytes : """ Convert a string to a byte array. """ # Convert the string to a byte array return int(string, 2).to_bytes((len(string) + 7) // 8, byteorder='big') def get_slot_count( event ) -> int : """ Get the number of slots in an event. """ # Get the timespan of the event start_time = datetime.datetime.combine(datetime.date.today(), event.end_time) end_time = datetime.datetime.combine(datetime.date.today(), event.start_time) timespan = abs(end_time - start_time) # Get the number of slots in the event days = event.date_set.count() slots_per_day = timespan.total_seconds() // event.slot_interval.total_seconds() return int(days * slots_per_day) def slots2grid( event : Event ) -> dict : """ Convert the slots of an event to data for the grid. """ # Get the number of slots in the event n_slots = get_slot_count(event) data = { 'days': [], 'rows': [], } # Get the timespan of the event start_time = datetime.datetime.combine(datetime.date.today(), event.end_time) end_time = datetime.datetime.combine(datetime.date.today(), event.start_time) timespan = abs(end_time - start_time) # Get the slots in a day slots_per_day = timespan.total_seconds() // event.slot_interval.total_seconds() # Fill the rows of the grid last_hour = None for i in range(slots_per_day): current_time = start_time + i * event.slot_interval data['rows'].append({ 'time': current_time, 'is_full_hour': current_time.hour != last_hour, }) last_hour = current_time.hour # Get the slots of each day participants = event.participant_set.all() participant_slot_strings = [slots2string(participant, n_slots) for participant in participants] max_occupancy = 0 for date in event.date_set.all(): # Get participants for each slot slot_participants = [[] for i in range(slots_per_day)] for i, participant in enumerate(participants): for j in range(slots_per_day): if participant_slot_strings[i][j] == '1': slot_participants[j].append(participant) # Fill the slots of the day slots = [] for ps in slot_participants: slots.append({ 'tooltip': ', '.join([p.user.username for p in ps]), 'occupancy': len(ps), }) max_occupancy = max(max_occupancy, len(ps)) day = { 'date': date.date, 'slots': slots, } data['days'].append(day)