class ProfileView(ApiView): http_method_names = ['get'] access_manager = acl.AccessManager(acl_accept=[acl.group_user]) response_form_class = ResponseForm def work(self, request, req, res): # Base info res['first_name'] = request.user.first_name res['last_name'] = request.user.last_name res['email'] = request.user.email res['groups'] = list(request.user.groups.values_list('name', flat=True)) # Extra info user_info = UserInfo.objects.get(user=request.user) res['shirt_size'] = user_info.shirt_size res['github'] = user_info.github res['linkedin'] = user_info.linkedin res['phone_number'] = user_info.phone_number res['diet'] = user_info.diet # Attendee Status info res['rsvp_confirmed'] = AttendeeStatus.objects.filter( hackathon=Hackathon.objects.current(), user=request.user, rsvp_submitted_at__isnull=False).exists() res['checked_in'] = AttendeeStatus.objects.filter( hackathon=Hackathon.objects.current(), user=request.user, checked_in_at__isnull=False).exists()
class ApprovedAndCheckedInView(ApiView): http_method_names = ['get'] access_manager = acl.AccessManager(acl_accept=[acl.group_organizer]) response_form_class = ResponseForm def work(self, request, req, res): judges = [] for info in JudgeInfo.objects.filter( hackathon=Hackathon.objects.current(), approved=True, attendee_status__checked_in_at__isnull=False): assignments = JudgingAssignment.objects.filter(judge=info) judges.append({ 'id': info.id, 'name': '{} {}'.format(info.user.first_name, info.user.last_name), 'assignments_pending': assignments.filter( status=JudgingAssignment.STATUS_PENDING).count(), 'assignments_completed': assignments.filter( status=JudgingAssignment.STATUS_COMPLETE).count(), 'assignments_canceled': assignments.filter( status=JudgingAssignment.STATUS_CANCELED).count(), }) res['judges'] = judges
class PendingHackAssignmentView(ApiView): http_method_names = ['get'] access_manager = acl.AccessManager(acl_accept=[acl.group_judge]) response_form_class = ResponseForm def work(self, request, req, res): hackathon = Hackathon.objects.current() # Make sure valid judge try: judge = JudgeInfo.objects.get(user=request.user) except JudgeInfo.DoesNotExist: raise ValidationError('Invalid user. Missing judge object') if not judge.approved or judge.hackathon != hackathon: raise ValidationError('You are not approved to judge this hackathon') # Get next assigned hacks' basic info hacks = [] assignments = JudgingAssignment.objects.filter( hackathon=hackathon, judge=judge, status=JudgingAssignment.STATUS_PENDING ).order_by('hack__table_number').all() for assignment in assignments: hack = assignment.hack hacks.append({ 'assignment_id': assignment.id, 'hack_name': hack.name, 'hack_table_number': hack.table_number, 'assignment_status': assignment.status }) res['hacks'] = hacks
class RegisterView(ApiView): request_form_class = RequestForm allowed_after_current_hackathon_ends = False access_manager = acl.AccessManager(acl_accept=[acl.group_user], acl_deny=[ acl.group_hacker, acl.group_judge, acl.group_pending_judge, acl.group_pending_hacker ]) def work(self, request, req, res): # Ensure is attendee current_hackathon = Hackathon.objects.current() attendee_status = AttendeeStatus.objects.get_or_create( user=request.user, hackathon=current_hackathon) JudgeInfo.objects.create(hackathon=current_hackathon, user=request.user, attendee_status=attendee_status, affiliation=req['affiliation'], organizer_contact=req['organizer_contact']) acl.add_user_to_group(request.user, acl.group_pending_judge) # Send email for confirmation email.send_template(to_email=request.user.email, to_first_name=request.user.first_name, to_last_name=request.user.last_name, subject='Judge Registration Submitted!', template_name='judge_register_waiting')
class AssignWifiCredentialsView(ApiView): request_form_class = RequestForm allowed_after_current_hackathon_ends = False access_manager = acl.AccessManager(acl_accept=[acl.group_organizer]) def work(self, request, req, res): attendee_info = AttendeeStatus.objects.filter(id=req['attendee_status_id']) if not attendee_info.exists(): raise ValidationError('Invalid id', params=['attendee_status_id']) user = attendee_info[0].user if WifiCred.objects.filter(assigned_user=user).exists(): raise ValidationError('Attendee already has wifi credentials', params=['attendee_status_id']) # Get new free wifi cred to assign credentials = WifiCred.objects.filter(hackathon=Hackathon.objects.current(), assigned_user__isnull=True) if not credentials.exists(): raise ValidationError('No more wifi codes to assign!') credentials = credentials.all() cred = credentials[random.randint(0, len(credentials)-1)] # Assign cred.assigned_user = user cred.save() # Email email.send_template_to_user(user, 'wifi_credentials', 'Wifi Credentials', { 'username': cred.username, 'password': cred.password })
class ResumeLinksCsv(StreamedCsvView): access_manager = acl.AccessManager(acl_accept=[acl.group_organizer]) file_name = 'HackFSU Approved Hackers\' Submitted Resumes.csv' @staticmethod def row_generator(request): h = Hackathon.objects.current() yield ['Approved Hackers\' Submitted Resumes'] yield [ 'First Name', 'Last Name', 'Email', 'School', 'Github', 'LinkedIn', 'Attended', 'Resume File Name', 'Resume URL' ] for hacker in HackerInfo.objects.filter(hackathon=h, approved=True): user_info = UserInfo.objects.get(user=hacker.user) row = [ hacker.user.first_name, hacker.user.last_name, hacker.user.email, str(hacker.school), user_info.github, user_info.linkedin, hacker.attendee_status.checked_in_at is not None ] if len(hacker.resume_file_name) > 0: row.extend([ hacker.resume_file_name.split('/')[-1], settings.URL_BASE + files.get_url(hacker.resume_file_name) ]) yield row
class RegisterView(ApiView): allowed_after_current_hackathon_ends = False request_form_class = RequestForm access_manager = acl.AccessManager( acl_accept=[acl.group_user], acl_deny=[acl.group_mentor, acl.group_pending_mentor]) def work(self, request, req, res): # Ensure is attendee current_hackathon = Hackathon.objects.current() attendee_status = AttendeeStatus.objects.get_or_create( user=request.user, hackathon=current_hackathon) MentorInfo.objects.create(hackathon=current_hackathon, user=request.user, attendee_status=attendee_status, affiliation=req['affiliation'], skills=req['skills'], motivation=req['motivation'], availability=req['availability']) acl.add_user_to_group(request.user, acl.group_pending_mentor) # Send email for confirmation email.send_template(to_email=request.user.email, to_first_name=request.user.first_name, to_last_name=request.user.last_name, subject='Mentor Registration Submitted!', template_name='mentor_register_waiting')
class UserRegistrationPage(PageView): template_name = "registration/user/index.html" access_manager = acl.AccessManager(acl_deny=[acl.group_user]) def get_access_denied_redirect_url(self, request): # Don't bother with the access denied flag, just redirect them to profile return '/user/profile'
class StartResetPage(PageView): template_name = 'user/password/start_reset/index.html' access_manager = acl.AccessManager(acl_deny=[acl.group_user]) def get_access_denied_redirect_url(self, request): # Don't bother with the access denied flag, just redirect them to profile return '/user/profile'
class CancelView(ApiView): access_manager = acl.AccessManager(acl_accept=[acl.group_judge]) request_form_class = RequestForm def work(self, request, req, res): # Make sure can submit assignment try: assignment = JudgingAssignment.objects.get( id=req['judging_assignment_id']) except JudgingAssignment.DoesNotExist: raise ValidationError('Invalid assignment id') if assignment.status != JudgingAssignment.STATUS_PENDING: raise ValidationError('Assignment is not pending') # Make sure assigned judge try: judge = JudgeInfo.objects.get(user=request.user) except JudgeInfo.DoesNotExist: raise ValidationError('Invalid user. Missing judge object') if assignment.judge != judge: raise ValidationError('Judge user not assigned to this assignment') # Cancel assignment assignment.status = JudgingAssignment.STATUS_CANCELED assignment.save()
class RsvpView(ApiView): request_form_class = RequestForm allowed_after_current_hackathon_ends = True access_manager = acl.AccessManager(acl_accept=[ acl.group_hacker, acl.group_mentor, acl.group_organizer, acl.group_judge ]) def authenticate(self, request): if not super().authenticate(request): return False # Add check to make sure not already RSVP'd return AttendeeStatus.objects.filter( hackathon=Hackathon.objects.current(), user=request.user, rsvp_submitted_at__isnull=True).exists() def work(self, request, req, res): status = AttendeeStatus.objects.get( hackathon=Hackathon.objects.current(), user=request.user) status.rsvp_result = True status.rsvp_submitted_at = timezone.now() status.extra_info = req['extra_info'] status.save()
class RequestPage(PageView): template_name = 'mentor/request/index.html' access_manager = acl.AccessManager(acl_accept=[acl.group_mentor]) def work(self, request): if not HelpRequest.objects.filter(id=self.kwargs['id']).exists(): raise Http404()
class ApprovedFullView(ApiView): http_method_names = ['get'] request_form_class = RequestForm response_form_class = ResponseForm access_manager = acl.AccessManager(acl_accept=[acl.group_organizer]) GET_PARAM_SEARCH = 'search[value]' def work(self, request, req, res): attendees = [] statuses = AttendeeStatus.objects.filter( hackathon=Hackathon.objects.current(), user__groups__name__in=[ acl.group_hacker, acl.group_mentor, acl.group_judge, acl.group_organizer ], ).order_by('user__first_name', 'user__last_name').distinct() res['recordsTotal'] = statuses.count() # Apply search filter filtered_statuses = statuses if self.GET_PARAM_SEARCH in request.GET: search = request.GET[self.GET_PARAM_SEARCH] if len(search) > 3: filtered_statuses = statuses.filter( Q(user__first_name__icontains=search) | Q(user__last_name__icontains=search) | Q(user__email__icontains=search) ) res['recordsFiltered'] = filtered_statuses.count() offset = req['start'] limit = offset + req['length'] returned_statuses = filtered_statuses.all()[offset:limit] for status in returned_statuses: attendee = { 'groups': list(status.user.groups.filter(name__in=[ acl.group_hacker, acl.group_mentor, acl.group_judge, acl.group_organizer ]).all().values_list('name', flat=True)) } if len(attendee['groups']) > 0: attendee['id'] = status.id attendee['name'] = '{} {}'.format(status.user.first_name, status.user.last_name) attendee['email'] = status.user.email attendee['checked_in'] = status.checked_in_at is not None attendee['has_wifi_credentials'] = hasattr(status.user, 'wificred') attendees.append(attendee) res['data'] = attendees res['draw'] = req['draw']
class GroupsView(ApiView): http_method_names = ['get'] access_manager = acl.AccessManager(acl_accept=[acl.group_user]) response_form_class = ResponseForm def work(self, request, req, res): res['groups'] = list(request.user.groups.values_list('name', flat=True))
class LogInView(ApiView): request_form_class = RequestForm access_manager = acl.AccessManager(acl_deny=[acl.group_user]) def work(self, request, req, res): log_user_in(request=request, email=req['email'].lower(), password=req['password'])
class OrganizerRegistrationPage(PageView): template_name = 'registration/organizer/index.html' access_manager = acl.AccessManager(acl_accept=[acl.group_user], acl_deny=[ acl.group_hacker, acl.group_organizer, acl.group_pending_hacker, acl.group_pending_organizer ])
class JudgeRegistrationPage(PageView): allowed_after_current_hackathon_ends = False template_name = 'registration/judge/index.html' access_manager = acl.AccessManager(acl_accept=[acl.group_user], acl_deny=[ acl.group_hacker, acl.group_judge, acl.group_pending_hacker, acl.group_pending_judge ])
class RegisterView(ApiView): request_form_class = RequestForm response_form_class = ResponseForm access_manager = acl.AccessManager(acl_deny=[acl.group_user]) def work(self, request: HttpRequest, req: dict, res: dict): # Clean fields req['email'] = req['email'].lower() req['first_name'] = req['first_name'].lower().capitalize() # Check captcha if not captcha.is_valid_response(req['g_recaptcha_response']): raise ValidationError('Captcha check failed', params=['g_recaptcha_response']) # Check if email (username) already in use if User.objects.filter(username=req['email']).exists(): raise ValidationError('Email already in use', params=['email']) # Attempt to create new user user = User.objects.create_user( username=req['email'], email=req['email'], password=req['password'] ) user.first_name = req['first_name'] user.last_name = req['last_name'] user.save() # Create respective UserInfo user_info = UserInfo( user=user, shirt_size=req['shirt_size'], github=req['github'], linkedin=req['linkedin'], diet=req['diet'], phone_number=req['phone_number'] ) user_info.save() # Send email for confirmation # email.send_template( # to_email=req['email'], # to_first_name=req['first_name'], # to_last_name=req['last_name'], # subject='HackFSU Account Created', # template_name='user_registered' # ) # Log user in try: log_user_in(request=request, email=req['email'], password=req['password']) res['logged_in'] = True except ValidationError: res['logged_in'] = False
class HackPage(PageView): allowed_after_current_hackathon_ends = False template_name = 'judge/hack/index.html' access_manager = acl.AccessManager(acl_accept=[acl.group_judge]) def work(self, request): if not JudgingAssignment.objects.filter( id=self.kwargs['id'], judge__user=request.user, status=JudgingAssignment.STATUS_PENDING).exists(): raise Http404()
class PostHacksView(ApiView): request_form_class = RequestForm access_manager = acl.AccessManager(acl_accept=[acl.group_judge]) def work(self, request: HttpRequest, req: dict, res: dict): current_hackathon = Hackathon.objects.current() judge = JudgeInfo.objects.get(hackathon=current_hackathon, user=request.user) # Tracker for whether the judge/device has a pending assignment judge_hack_assignment = list( Hack.objects.with_active_judge(judge).values_list('table_number', flat=True)) has_active_assignment = len(judge_hack_assignment) is not 0 # If POST, make sure the data fits the hacks they were assigned. # Accept the ratings for the hacks they received. if has_active_assignment: order = get_order(req) logging.warn('incoming score submissions: ' + str(order.values())) logging.warn('the assignment was: ' + str(judge_hack_assignment)) # If the hacks they sent back match their assignment... if set(order.values()) == set(judge_hack_assignment): # ... accept scores ... for rank, table in order.items(): hack = Hack.objects.from_table_number(table) hack.total_judge_score += (4 - int(rank)) hack.save() # ... annotate superlatives ... nominations = get_superlatives(req) logging.info(nominations) for table, superlative_names in nominations.items(): hack = Hack.objects.get(table_number=table) for name in superlative_names: superlative = JudgingCriteria.objects.get(name=name) hack.nomination_set.create(superlative=superlative) # ... and remove judge from assignments for table_num in judge_hack_assignment: hack = Hack.objects.from_table_number(table_num) hack.current_judges.remove(judge) hack.judges.add(judge) # hack.save() else: raise ValidationError('These are the wrong tables', params=['order']) else: raise ValidationError('You don\'t have an assignment.')
class SingleView(ApiView): http_method_names = ['get'] response_form_class = ResponseClass access_manager = acl.AccessManager(acl_accept=[acl.group_mentor]) def work(self, request, req, res): try: help_request = HelpRequest.objects.get(id=self.kwargs['id']) except ObjectDoesNotExist: raise ValidationError('Invalid id', params=['id']) res['help_request'] = help_request.json(request.user)
class AttendeesCheckedInCsv(StreamedCsvView): access_manager = acl.AccessManager(acl_accept=[acl.group_organizer]) file_name = 'Checked in Attendees.csv' @staticmethod def row_generator(request): h = Hackathon.objects.current() yield ['First Name', 'Last Name'] for status in AttendeeStatus.objects.filter( hackathon=h, checked_in_at__isnull=False): yield [status.user.first_name, status.user.last_name]
class AllView(ApiView): http_method_names = ['get'] response_form_class = ResponseClass access_manager = acl.AccessManager(acl_accept=[acl.group_mentor]) def work(self, request, req, res): help_requests = [] for hr in HelpRequest.objects.filter( hackathon=Hackathon.objects.current()): help_requests.append(hr.json(request.user)) res['help_requests'] = help_requests
class GetHacksView(ApiView): http_method_names = ['get'] # Override to allow GET response_form_class = ResponseForm access_manager = acl.AccessManager(acl_accept=[acl.group_judge]) def work(self, request: HttpRequest, req: dict, res: dict): current_hackathon = Hackathon.objects.current() judge = JudgeInfo.objects.get(hackathon=current_hackathon, user=request.user) # Tracker for whether the judge/device has a pending assignment judge_hack_assignment = list( Hack.objects.with_active_judge(judge).values_list('table_number', flat=True)) has_active_assignment = len(judge_hack_assignment) is not 0 logging.warn('incoming judge hack assignment: ' + str(judge_hack_assignment)) # If they don't have a hack assignment, make a new one if not has_active_assignment: # New assignment is: # - 3 hacks # - from current expo # - least judged hacks # - with fewest active judges # - that isn't a repeat assignment current_expo = JudgingExpo.objects.current( hackathon=current_hackathon) hacks = Hack.objects.from_expo(current_expo) \ .without_previous_judge(judge) \ .annotate(num_judges=Count('current_judges')) \ .order_by('times_judged', 'num_judges')[:3] judge_hack_assignment = list( hacks.values_list('table_number', flat=True)) # Add judge to hack's active judges for table_num in judge_hack_assignment: hack = Hack.objects.from_table_number(table_num) hack.current_judges.add(judge) superlative_categories = JudgingCriteria.objects.all() logging.warn('outgoing judge hack assignment: ' + str(judge_hack_assignment)) res['hacks'] = judge_hack_assignment res['superlatives'] = list( superlative_categories.values_list('name', flat=True)) res['expo'] = JudgingExpo.objects.current( hackathon=current_hackathon).name
class RosterCsv(StreamedCsvView): access_manager = acl.AccessManager(acl_accept=[acl.group_organizer]) file_name = 'organizer_roster.csv' @staticmethod def row_generator(request): h = Hackathon.objects.current() yield ['First Name', 'Last Name'] for info in OrganizerInfo.objects.filter(hackathon=h, approved=True): yield [ info.user.first_name, info.user.last_name ]
class BySchoolCsv(StreamedCsvView): access_manager = acl.AccessManager(acl_accept=[acl.group_organizer]) file_name = 'hackers_by_school.csv' @staticmethod def row_generator(request): h = Hackathon.objects.current() yield ['School', 'First Name', 'Last Name', 'Email', 'RSVP=yes'] for hacker in HackerInfo.objects.filter(hackathon=h, approved=True): yield [ str(hacker.school), hacker.user.first_name, hacker.user.last_name, hacker.user.email, 'Y' if hacker.attendee_status.rsvp_result else '' ]
class ScanEventsView(ApiView): class ResponseForm(forms.Form): events = JsonField() http_method_names = ['get'] response_form_class = ResponseForm access_manager = acl.AccessManager(acl_accept=[acl.group_organizer]) def work(self, request, req, res): scan_events = ScanEvent.objects.all() events_list = [] for event in scan_events: events_list.append({'id': event.id, 'name': event.name}) res['events'] = events_list
class AssignHacksView(ApiView): request_form_class = RequestForm response_form_class = ResponseForm allowed_after_current_hackathon_ends = False access_manager = acl.AccessManager(acl_accept=[acl.group_organizer]) def work(self, request, req, res): hackathon = Hackathon.objects.current() # Make sure valid judge try: judge = JudgeInfo.objects.get(id=req['judge_info_id']) except JudgeInfo.DoesNotExist: raise ValidationError('Invalid id', params=['judge_info_id']) if not judge.approved or judge.hackathon != hackathon: raise ValidationError('Judge is not approved for this hackathon', params=['judge_info_id']) # Get the current expo expo = JudgingExpo.objects.current(hackathon=hackathon) if expo is None: raise ValidationError( 'There is not an expo going on to get hacks for!') # Check if they still have any pending assignments pending_assignments = JudgingAssignment.objects.filter( judge=judge, status=JudgingAssignment.STATUS_PENDING).count() if pending_assignments > 0: raise ValidationError( 'Judge still has pending assignments. Tell them to either cancel or grade them.' ) new_assignments = 0 possible_hacks = get_sorted_possible_hacks(expo, hackathon, judge, req['max_judge_count']) for i in range(len(possible_hacks)): # Assign next JudgingAssignment.objects.create(hackathon=hackathon, judge=judge, hack=possible_hacks[i]) new_assignments += 1 if new_assignments >= req['max_hacks']: # Max hacks assigned, stop break res['new_assignments'] = new_assignments
class ControlledView(View): http_method_names = ['post', 'get'] access_manager = acl.AccessManager() def get(self, request): return self.pre_process(request, request.GET) def post(self, request): return self.pre_process(request, request.POST) def pre_process(self, request, input_data: dict): """ Validates input and attempts to preform work() logic. Returns the correct JsonResponse """ # Authenticate Access if not self.authenticate(request): error_response = self.return_error_response(request) if error_response is None: raise Http404() return error_response try: return self.process(request, input_data) except Exception as e: error = InternalServerError(e) request_info = self.format_request_info(request, input_data) logging.error(request_info) error.log() if not settings.DEBUG: error.email_log_to_dev(request_info=request_info, user=request.user) return error.json_response(include_message=False) def authenticate(self, request): """ To be overridden if necessary. Should still be called with super """ return self.access_manager.check_user(request.user) def return_error_response(self, request) -> HttpResponse: pass def process(self, request, input_data): pass @staticmethod def format_request_info(request, input_data): return '\tRequest: {}\n\tRaw Input: {}'.format(str(request), str(input_data))
class GetView(ApiView): http_method_names = ['get'] request_form_class = RequestForm response_form_class = ResponseForm access_manager = acl.AccessManager(acl_accept=[acl.group_user]) def work(self, request: HttpRequest, req: dict, res: dict): schools = [] if req['include_user_submitted']: schools.extend(School.objects.all()) else: schools.extend(School.objects.filter(user_submitted=False)) school_data = list() for s in schools: school_data.append({'id': s.id, 'name': s.name}) res['school_choices'] = school_data