Example #1
0
def top_food_report(account_id, source_id, survey_id, token_info):
    _validate_account_access(token_info, account_id)

    with Transaction() as t:
        vioscreen_repo = VioscreenRepo(t)

        # Vioscreen username is our survey_id
        status = vioscreen_repo.get_vioscreen_status(account_id, source_id,
                                                     survey_id)
        if status != 3:
            # Oops, we don't have results available for this one
            raise NotFound("No such survey recorded")

        vio = VioscreenAdminAPI()
        sessions = vio.sessions(survey_id)
        # Looks like vioscreen supports multiple sessions per user, do we care?
        session_id = sessions[0]['sessionId']
        report = vio.top_food_report(session_id)

        response = make_response(report)
        response.headers.set("Content-Type", "application/pdf")
        # TODO: Do we want it to download a file or be embedded in the html?
        # response.headers.set('Content-Disposition',
        #                      'attachment',
        #                      filename='top-food-report.pdf')

        return response
Example #2
0
def _submit_vioscreen_status(account_id, source_id, info_str):
    # get information out of encrypted vioscreen url
    info = vioscreen.decode_key(info_str).decode("utf-8")
    vio_info = {}
    for keyval in info.split("&"):
        key, val = keyval.split("=")
        vio_info[key] = val

    with Transaction() as t:
        vio_repo = VioscreenRepo(t)

        # Add the status to the survey
        vio_repo.upsert_vioscreen_status(account_id, source_id,
                                         vio_info["username"],
                                         int(vio_info["status"]))
        t.commit()

    response = flask.Response()
    response.status_code = 201
    # TODO FIXME HACK:  This location can't actually return any info about ffq!
    #  But I need SOME response that contains the survey_id or client can't
    #  associate the survey with a sample.
    response.headers['Location'] = '/api/accounts/%s' \
                                   '/sources/%s' \
                                   '/surveys/%s' % \
                                   (account_id,
                                    source_id,
                                    vio_info["username"])
    return response
Example #3
0
    def test_insert_ffq(self):
        with Transaction() as t:
            vr = VioscreenRepo(t)
            vr.insert_ffq(self.FFQ)

            # if we've successfully inserted, we should be able to use
            # another repo to get a subset of data

            vs = VioscreenSupplementsRepo(t)
            supp = vs.get_supplements(VIOSCREEN_SESSION.sessionId)
            self.assertEqual(self.supp, supp)
    def find_survey_template_id(self, survey_answers_id):
        # TODO FIXME HACK:  There has GOT TO BE an easier way!
        with self._transaction.cursor() as cur:
            cur.execute(
                "SELECT survey_id, survey_question_id "
                "FROM survey_answers "
                "WHERE survey_id=%s "
                "LIMIT 1", (survey_answers_id, ))

            rows = cur.fetchall()

            cur.execute(
                "SELECT survey_id, survey_question_id "
                "FROM survey_answers_other "
                "WHERE survey_id=%s "
                "LIMIT 1", (survey_answers_id, ))
            rows += cur.fetchall()

            # TODO:  We probably can't merge the PR with this change, need
            #  a policy to resolve these survey ids (unless they only happen
            #  in dev builds)
            # TODO:  It's even worse than I feared.  Some of our primary
            #  surveys are ALSO vioscreen surveys with the same key. wtf.
            if len(rows) == 0:
                vioscreen_repo = VioscreenRepo(self._transaction)
                status = vioscreen_repo._get_vioscreen_status(
                    survey_answers_id)
                if status is not None:
                    return SurveyTemplateRepo.VIOSCREEN_ID
                else:
                    return None
                    # TODO: Maybe this should throw an exception, but doing so
                    #  locks the end user out of the minimal implementation
                    #  if they submit an empty survey response.
                    # raise RepoException("No answers in survey: %s" %
                    #                     survey_answers_id)

            arbitrary_question_id = rows[0][1]
            cur.execute(
                "SELECT surveys.survey_id FROM "
                "group_questions "
                "LEFT JOIN surveys USING (survey_group) "
                "WHERE survey_question_id = %s", (arbitrary_question_id, ))

            survey_template_id = cur.fetchone()[0]
            return survey_template_id
    def find_survey_template_id(self, survey_answers_id):
        # TODO FIXME HACK:  There has GOT TO BE an easier way!
        with self._transaction.cursor() as cur:
            cur.execute("SELECT survey_id, survey_question_id "
                        "FROM survey_answers "
                        "WHERE survey_id=%s "
                        "LIMIT 1",
                        (survey_answers_id,))

            rows = cur.fetchall()

            cur.execute("SELECT survey_id, survey_question_id "
                        "FROM survey_answers_other "
                        "WHERE survey_id=%s "
                        "LIMIT 1",
                        (survey_answers_id,))
            rows += cur.fetchall()

            if len(rows) == 0:
                vioscreen_repo = VioscreenRepo(self._transaction)
                status = vioscreen_repo.get_vioscreen_status(survey_answers_id)
                if status is not None:
                    return SurveyTemplateRepo.VIOSCREEN_ID
                else:
                    return None
                    # TODO: Maybe this should throw an exception, but doing so
                    #  locks the end user out of the minimal implementation
                    #  if they submit an empty survey response.
                    # raise RepoException("No answers in survey: %s" %
                    #                     survey_answers_id)

            arbitrary_question_id = rows[0][1]
            cur.execute("SELECT surveys.survey_id FROM "
                        "group_questions "
                        "LEFT JOIN surveys USING (survey_group) "
                        "WHERE survey_question_id = %s",
                        (arbitrary_question_id,))

            survey_template_id = cur.fetchone()[0]
            return survey_template_id
    def survey_template_id_and_status(self, survey_answers_id):
        # TODO FIXME HACK:  There has GOT TO BE an easier way!
        with self._transaction.cursor() as cur:
            cur.execute(
                "SELECT survey_id, survey_question_id "
                "FROM survey_answers "
                "WHERE survey_id=%s "
                "LIMIT 1", (survey_answers_id, ))

            rows = cur.fetchall()

            cur.execute(
                "SELECT survey_id, survey_question_id "
                "FROM survey_answers_other "
                "WHERE survey_id=%s "
                "LIMIT 1", (survey_answers_id, ))
            rows += cur.fetchall()

            if len(rows) == 0:
                # see if it's vioscreen
                vioscreen_repo = VioscreenRepo(self._transaction)
                status = vioscreen_repo._get_vioscreen_status(
                    survey_answers_id)
                if status is not None:
                    return SurveyTemplateRepo.VIOSCREEN_ID, status

                # see if it's the Polyphenol FFQ
                try:
                    uuid.UUID(survey_answers_id)
                    cur.execute(
                        """SELECT EXISTS (
                                   SELECT polyphenol_ffq_id
                                   FROM ag.polyphenol_ffq_registry
                                   WHERE polyphenol_ffq_id=%s)""",
                        (survey_answers_id, ))
                    if cur.fetchone()[0] is True:
                        return SurveyTemplateRepo.POLYPHENOL_FFQ_ID, None
                except ValueError:
                    # Note: we don't care about the error, just means it's not
                    # the Polyphenol FFQ
                    pass

                # see if it's myfoodrepo
                cur.execute(
                    """SELECT EXISTS (
                                   SELECT myfoodrepo_id
                                   FROM myfoodrepo_registry
                                   WHERE myfoodrepo_id=%s)""",
                    (survey_answers_id, ))
                if cur.fetchone()[0] is True:
                    return SurveyTemplateRepo.MYFOODREPO_ID, None
                else:
                    # not vioscreen and not myfoodrepo?

                    return None, None
                    # TODO: Maybe this should throw an exception, but doing so
                    #  locks the end user out of the minimal implementation
                    #  if they submit an empty survey response.
                    # raise RepoException("No answers in survey: %s" %
                    #                     survey_answers_id)

            arbitrary_question_id = rows[0][1]
            cur.execute(
                "SELECT surveys.survey_id FROM "
                "group_questions "
                "LEFT JOIN surveys USING (survey_group) "
                "WHERE survey_question_id = %s", (arbitrary_question_id, ))

            survey_template_id = cur.fetchone()[0]
            # Can define statuses for our internal surveys later if we want
            return survey_template_id, None
def fetch_ffqs():
    MAX_FETCH_SIZE = 100

    vio_api = VioscreenAdminAPI(perform_async=False)

    # obtain our current unfinished sessions to check
    with Transaction() as t:
        r = VioscreenSessionRepo(t)
        not_represented = r.get_unfinished_sessions()

    # collect sessions to update
    unable_to_update_session = []
    updated_sessions = []
    for sess in enumerate(not_represented):
        # update session status information
        try:
            session_detail = vio_api.session_detail(sess)
        except:  # noqa
            unable_to_update_session.append(sess)
        else:
            updated_sessions.append(session_detail)

    # perform the update after we collect everything to reduce teh length of
    # time we hold the transaction open
    with Transaction() as t:
        r = VioscreenSessionRepo(t)
        for session_detail in updated_sessions:
            r.upsert_session(session_detail)
        t.commit()

    with Transaction() as t:
        vs = VioscreenSessionRepo(t)
        ffqs_not_represented = vs.get_missing_ffqs()

    # fetch ffq data for sessions we don't yet have it from
    failed_ffqs = []
    for sess in ffqs_not_represented[:MAX_FETCH_SIZE]:
        try:
            error, ffq = vio_api.get_ffq(sess.sessionId)
        except Exception as e:  # noqa
            failed_ffqs.append((sess.sessionId, str(e)))
            continue

        if error:
            failed_ffqs.append((sess.sessionId, repr(error)))
        else:
            # the call to get_ffq is long, and the data from many ffqs is
            # large so let's insert as we go
            with Transaction() as t:
                vs = VioscreenRepo(t)
                vs.insert_ffq(ffq)
                t.commit()

    if len(failed_ffqs) > 0 or len(unable_to_update_session) > 0:
        payload = ''.join([
            '%s : %s\n' % (repr(s), m)
            for s, m in failed_ffqs + unable_to_update_session
        ])
        send_email(SERVER_CONFIG['pester_email'], "pester_daniel", {
            "what": "Vioscreen ffq insert failed",
            "content": payload
        }, EN_US)
Example #8
0
 def test_get_ffq(self):
     with Transaction() as t:
         vr = VioscreenRepo(t)
         vr.insert_ffq(self.FFQ)
         obs = vr.get_ffq(VIOSCREEN_SESSION.sessionId)
         self.assertEqual(obs, self.FFQ)