Esempio n. 1
0
def authorize_new_patient():
    """
    This is called once a patient clicks the confirmation link in their email.
    Redirect a new patient to Fitbit to authorize our app via OAuth 2 Authorization Grant Flow, and
    then receives access token (for making API calls on the user's behalf) as well as a
    refresh token (for obtaining a new access token when the access token expires).
    """
    access_code = request.args.get("code")
    invite_id = request.args.get("state")
    api = Fitbit()

    # Require users to be invited by a physician. Only occurs when they receive an email w/ invite_id (aka "state").
    if invite_id is None:
        flash(
            "Error: an authorization token is required. Please use the confirmation link that was emailed to you.",
            "warning",
        )
        return redirect("/")

    if access_code is None:
        auth_url = api.get_authorization_uri(invite_id)
        return redirect(auth_url)

    try:
        token = api.get_access_token(access_code)
    except Exception as e:
        flash(e.message, "warning")
        return redirect("/")

    try:
        response, token = api.api_call(token, "/1/user/-/profile.json")
    except Exception as e:
        flash(e.message, "warning")
        return redirect("/")

    # fullname = response['user']['fullName']  # Using name entered by Physician on invite instead.
    fitbit_id = response["user"]["encodedId"]

    try:
        invite = PatientInvite.objects.get(id=invite_id)
        if not invite.accepted:
            invite.accepted = True
            PatientInvite.delete(invite)

            try:
                existing_patient = Patient.objects.get(slug=fitbit_id)
                existing_patient.token = token["access_token"]
                existing_patient.refresh = token["refresh_token"]
                existing_patient.save()
                new_patient = existing_patient

            except DoesNotExist:
                new_patient = Patient(
                    slug=fitbit_id,
                    first_name=invite.first_name,
                    last_name=invite.last_name,
                    email=invite.email,
                    token=token["access_token"],
                    refresh=token["refresh_token"],
                    date_joined=datetime.now(),
                    health_data_per_day=[],
                    date_last_data_fetch="",
                )
                new_patient.save()

                # By default, get 5 days worth of data for the brand new patient
                new_patient_data = PatientData(new_patient)
                PatientData.get_heart_rate_data_for_x_days(new_patient_data, 5)
                PatientData.get_activity_data_for_x_days(new_patient_data, 5)

            # Now save this patient to the inviting physician's list of patients.
            inviting_physician = invite.inviting_physician
            inviting_physician.patients.append(new_patient)
            inviting_physician.save()

            # Now attach a generic config to Patient for the Physician to edit later
            min_hr_default = {"value": 50, "window": 15}  # BPS / minute
            max_hr_default = {"value": 110, "window": 15}  # BPS / minute
            min_steps_default = {"value": 500, "window": 60 * 12}  # steps / 12 hr
            max_steps_default = {"value": 5000, "window": 60}  # steps / 1 hr
            config = PatientConfig(
                minHR=min_hr_default,
                maxHR=max_hr_default,
                minSteps=min_steps_default,
                maxSteps=max_steps_default,
                patient=new_patient,
            )
            inviting_physician.patient_config.append(config)
            inviting_physician.save()

            return redirect("/patient-registered?name=" + invite.first_name)
        else:
            flash("It appears you've already confirmed this account.", "warning")
            return redirect("/")

    except DoesNotExist as e:
        flash(e.__str__(), "warning")
        return redirect("/")
Esempio n. 2
0
def drop():
    from recover.models import Patient, User, PatientInvite
    PatientInvite.drop_collection()
    Patient.drop_collection()
    User.drop_collection()