def get(self, instance_id): auth_response = authenticate(self, [Permissions.READ_QUESTION]) if auth_response["valid"]: instance = InstanceService.get_instance(instance_id) state = StateService.get_next_state_in_instance(instance) if state is None: self.set_status(404) self.write('{"status":"error","message":"Survey does not exist"}') self.finish() else: survey = SurveyService.get_survey(instance.survey_id) if str(survey.owner_id) == auth_response["owner_id"]: if state.status == Status.CREATED_START: self.set_status(200) self.write('{"status":"success","status":"NOT STARTED"}') self.flush() elif state.status == Status.TERMINATED_COMPLETE: self.set_status(200) self.write('{"status":"success","status":"COMPLETE"}') self.flush() else: self.set_status(200) self.write('{"status":"success","status":"IN PROGRESS"}') self.flush() else: self.set_status(403) self.write('{"status":"error","message":"Owner does not have authorization to see this survey"}') self.flush()
def get_by_owner(owner_id, survey_id=None, status=None): instances = Model.repository.instances surveys = Model.repository.surveys if survey_id is None: instance_list = instances.select(InnerJoin(instances, surveys, instances.survey_id, InnerJoin.EQUAL, surveys.id), Where(surveys.owner_id, Where.EQUAL, owner_id), force_list=True) else: instance_list = instances.select( InnerJoin(instances, surveys, instances.survey_id, InnerJoin.EQUAL, surveys.id), Where(surveys.owner_id, Where.EQUAL, owner_id).AND(surveys.id, Where.EQUAL, survey_id), force_list=True) if status is None: return instance_list else: final_list = [] for instance in instance_list: state = StateService.get_next_state_in_instance( instance, status) if state is not None and status.value == state.status: final_list.append(instance) return final_list
def start_instance(instance): instance_id = instance.id print("Starting instance " + str(instance_id)) survey = SurveyService.get_survey(instance.survey_id) timeout_minutes = survey.timeout timeout_timestamp = datetime.now(tz=pytz.utc) + timedelta( minutes=timeout_minutes) StateService.create_state(instance_id, 1, Status.CREATED_START, timeout_timestamp, 0) participants = ParticipantService.get_participants_in_enrollment( survey.enrollment_id) plugin_ids = set() for participant in participants: plugin_ids.add(participant.plugin_id) for plugin_id in plugin_ids: PluginService.poke(plugin_id, survey.id)
def post(self, instance_id): auth_response = authenticate(self, [Permissions.WRITE_SURVEY]) if auth_response["valid"]: data = json_decode(self.request.body) if 'action' in data: action = data['action'].lower() else: self.set_status(400) self.write('{"status":"error","message":"Missing action parameter"}') self.flush() return if action == 'start': instance = InstanceService.get_instance(instance_id) state = StateService.get_next_state_in_instance(instance, Status.CREATED_START) if state is not None: survey = SurveyService.get_survey(instance.survey_id) if str(survey.owner_id) == auth_response["owner_id"]: state.status = Status.AWAITING_USER_RESPONSE.value StateService.update_state(state) self.set_status(200) self.write('{"status":"success","status":"STARTED"}') self.flush() else: self.set_status(403) self.write('{"status":"error","message":"Owner does not have authorization to start survey"}') self.flush() else: self.set_status(410) self.write('{"status":"error","message":"Survey already started, or does not exist"}') self.flush() else: self.set_status(400) self.write('{"status":"error","message":"Invalid action parameter"}') self.flush()
def get(self, instance_id): auth_response = authenticate(self, [Permissions.READ_QUESTION]) if auth_response["valid"]: instance = InstanceService.get_instance(instance_id) state = StateService.get_next_state_in_instance(instance, Status.AWAITING_USER_RESPONSE) if state is None: self.set_status(410) response = { "status": "error", "message": "No response was expected for this survey" } else: survey = SurveyService.get_survey(instance.survey_id) if str(survey.owner_id) == auth_response['owner_id']: question_service = QuestionService() question = question_service.get(survey.protocol_id, state.question_number) if question is not None: self.set_status(200) response = { "status": "success", "question_number": state.question_number, "question_text": question.question_text, "survey_end": question.final } else: self.set_status(410) response = { "status": "error", "message": "No more questions in this survey" } else: self.set_status(403) response = { "status": "error", "message": "Owner has not registered plugin" } response_json = json.dumps(response) logger.debug(response_json) self.write(response_json) self.flush()
def get(self, instance_id, question_number): auth_response = authenticate(self, [Permissions.READ_QUESTION]) if auth_response['valid']: instance = InstanceService.get_instance(instance_id) instance_id = instance.id state = StateService.get_state_by_instance_and_question(instance, question_number) if state is None: self.set_status(404) self.write('{"status":"error","message":"Question or survey does not exist"}') self.finish() else: survey = SurveyService.get_survey(instance.survey_id) question_service = QuestionService() question = question_service.get(survey.protocol_id, state.question_number) if question is None: self.set_status(404) self.write('{"status":"error","message":"Question does not exist"}') self.finish() else: q_text = question.question_text if state.status == Status.TERMINATED_COMPLETE: response_service = ResponseService() survey_id = instance.survey_id response_set = response_service.get_response_set(survey_id, instance_id) response = response_set.get_response(question.variable_name) self.set_status(200) self.write('{"status":"success","question_text":"' + q_text + '","responded":"True","response:":"' + response + '"') self.finish() else: self.set_status(200) self.write('{"status":"success","question_text":"' + q_text + '","responded":"False"') self.finish()
def post(self, instance_id): auth_response = authenticate(self, [Permissions.WRITE_RESPONSE]) if auth_response["valid"]: data = json_decode(self.request.body) if 'response' in data: response = data['response'] contact = data['contact'] else: self.set_status(400) self.write('{"status":"error","message":"Missing response parameter"}') return instance = InstanceService.get_instance(instance_id) if instance is None: self.set_status(410) self.write('{"status":"error","message":"No response was expected for this survey"}') self.finish() return instance_id = instance.id # Ensure that id is of right type state = StateService.get_next_state_in_instance(instance, Status.AWAITING_USER_RESPONSE) if state is not None and state.status is not Status.NO_RESPONSE_REQUIRED: survey = SurveyService.get_survey(instance.survey_id) if str(survey.owner_id) == auth_response["owner_id"]: question_number = state.question_number question_service = QuestionService() question = question_service.get(survey.protocol_id, question_number) now = datetime.now(tz=pytz.utc) now_csv_entry = str(datetime.now(tz=pytz.utc)) loaddata = LoadData() participant_id = loaddata.sendparticpantid(contact) loaddata_response = LoadData1() #loaddata_response.concatresponse(participant_id,question_number,response, now_csv_entry[:10],now_csv_entry[11:16]) if question is not None: if question.final: state.status = Status.TERMINATED_COMPLETE.value StateService.update_state(state) self.set_status(200) self.write('{"status":"success","response_accepted":"False","reason":"Survey has finished"}') self.flush() elif state.timeout.replace(tzinfo=pytz.utc) < now: state.status = Status.TERMINATED_TIMEOUT.value state.save() self.set_status(200) self.write( '{"status":"success","response_accepted":"False","reason":"Survey has timed out"}') else: state.status = Status.PROCESSING_USER_RESPONSE.value StateService.update_state(state) loaddata_response.concatresponse(participant_id,question_number,response, now_csv_entry[:10]) new_questions = question.process(response) if new_questions == 'INV_RESP': state.status = Status.AWAITING_USER_RESPONSE.value StateService.update_state(state) self.set_status(200) self.write('{"status":"success","response_accepted":"False","reason":"Invalid Response","pass_along_message":"' + question.invalid_message + '"}') self.flush() else: response_service = ResponseService() variable_name = question.variable_name survey_id = instance.survey_id response_service.insert_response(survey_id, instance_id, variable_name, response) if new_questions is not None: for new_question in new_questions: #print("Is this the final question", isFinal) #if not new_question.final: if not question.final: status = Status.CREATED_MID else: status = Status.NO_RESPONSE_REQUIRED StateService.create_state(instance_id, new_question[0][1], status, state.timeout, new_question[1]) state.status = Status.TERMINATED_COMPLETE.value StateService.update_state(state) new_state = StateService.get_next_state_in_instance(instance, Status.CREATED_MID) new_state.status = Status.AWAITING_USER_RESPONSE.value StateService.update_state(new_state) self.set_status(200) self.write('{"status":"success","response_accepted":"True"}') self.flush() else: self.set_status(410, "No response was expected for this survey") self.write('{"status":"error","message":"No response was expected for this survey"}') self.finish() else: self.set_status(403) self.write('{"status":"error","message":"Owner does not have authorization to modify survey"}') self.flush() else: self.set_status(410) self.write('{"status":"error","message":"No response was expected for this survey"}') self.finish()
def run_loop(): logger.info("Starting instance service loop") next_warning = {} while True: logger.info("Running instance service loop") instances = InstanceService.get_current_instances() if instances is not None: logger.info("%d instances existing", len(instances)) not_started = [] in_progress = [] finished = [] for instance in instances: latest = StateService.get_next_state_in_instance(instance) if latest is None: not_started.append(instance) else: in_progress.append(instance) now = datetime.now(tz=pytz.utc) for instance in in_progress: unfinished = StateService.get_unfinished_states(instance) if unfinished is None or len(unfinished) is 0: finished.append(instance) elif unfinished[0].timeout.replace(tzinfo=pytz.utc) < now: InstanceService.send_message_for_instance( instance, "Survey has expired") else: if instance.id not in next_warning: next_warning[instance.id] = now + timedelta( minutes=5) else: if now > next_warning[instance.id]: expires = StateService.get_next_state_in_instance(instance).timeout\ .replace(tzinfo=pytz.utc) now_ts = time.mktime(now.timetuple()) expires_ts = time.mktime(expires.timetuple()) delta = str(int((expires_ts - now_ts) / 60)) message = "Warning - survey expires in " + delta + " minutes" InstanceService.send_message_for_instance( instance, message) next_warning[instance.id] = now + timedelta( minutes=5) logger.info( "%d instances not started, %d instances in progress, %d instances awaiting purge", len(not_started), len(in_progress), len(finished)) if len(finished) > 0: logger.info("Purging instances: %s", str(finished)) StateService.delete_states_for_instances(finished) InstanceService.delete_instances(finished) if instance.id in next_warning: del next_warning[instance.id] if len(not_started) > 0: logger.info("Starting instances: %s", str(not_started)) for instance in not_started: InstanceService.start_instance(instance) else: logger.info("No instances exist") time.sleep(30)