def notify_duration_exceeded(self, participants, reference_time): """The bot participant has been working longer than the time defined in the "duration" config value. """ for participant in participants: participant.status = "rejected" session.commit()
def notify_duration_exceeded(self, participants, reference_time): """The participant has exceed the maximum time for the activity, defined in the "duration" config value. We need find out the assignment status on MTurk and act based on this. """ unsubmitted = [] for participant in participants: summary = ParticipationTime(participant, reference_time, self.config) status = self._mturk_status_for(participant) if status == "Approved": participant.status = "approved" session.commit() elif status == "Rejected": participant.status = "rejected" session.commit() elif status == "Submitted": self._resend_submitted_rest_notification_for(participant) self._message_researcher(self._resubmitted_msg(summary)) logger.warning( "Error - submitted notification for participant {} missed. " "A replacement notification was created and sent, " "but proceed with caution.".format(participant.id)) else: self._send_notification_missing_rest_notification_for( participant) unsubmitted.append(summary) disable_hit = self.config.get("disable_when_duration_exceeded") if disable_hit and unsubmitted: self._disable_autorecruit() self.close_recruitment() pick_one = unsubmitted[0] # message the researcher about the one of the participants: self._message_researcher(self._cancelled_msg(pick_one)) # Attempt to force-expire the hit via boto. It's possible # that the HIT won't exist if the HIT has been deleted manually. try: self.mturkservice.expire_hit(pick_one.participant.hit_id) except MTurkServiceException as ex: logger.exception(ex)
def recruiters(self, n=1): """Iterator that provides recruiters along with the participant count to be recruited for up to `n` participants. We use the `Recruitment` table in the db to keep track of how many recruitments have been requested using each recruiter. We'll use the first one from the specification that hasn't already reached its quota. """ recruit_count = 0 while recruit_count <= n: counts = dict( session.query(Recruitment.recruiter_id, func.count(Recruitment.id)).group_by( Recruitment.recruiter_id).all()) for recruiter_id, target_count in self.spec: remaining = 0 count = counts.get(recruiter_id, 0) if count >= target_count: # This recruiter quota was reached; # move on to the next one. counts[recruiter_id] = count - target_count continue else: # Quota is still available; let's use it. remaining = target_count - count break else: return num_recruits = min(n - recruit_count, remaining) # record the recruitments and commit for i in range(num_recruits): session.add(Recruitment(recruiter_id=recruiter_id)) session.commit() recruit_count += num_recruits yield by_name(recruiter_id), num_recruits