Example #1
0
def fields_post(data: M.SIField, as_user: str = None, viewer: M.User = Depends(fastapi_users.get_current_user)):
    user, snooping = getuser(viewer, as_user)
    if snooping: return cant_snoop()
    f = M.Field(**data.dict())
    user.fields.append(f)
    db.session.commit()
    db.session.refresh(f)
    return f
Example #2
0
    def submit_fields(self, uid, db, client=None, header=None):
        if not USE: return
        # if sess, it's coming from GPU: save to DB. If client, coming from server: POST.
        for i in list(range(10)):
            field = dict(
                type='fivestar',
                name=str(i),
                default_value='average',
            )
            fid = None
            if client:
                res = client.post("/fields", json=field, **header)
                assert res.status_code == 200
                fid = res.json()['id']
            else:
                field = M.Field(**field, user_id=uid)
                db.add(field)
                db.commit()
                db.refresh(field)
                fid = field.id

            # create field-entries for x days
            # stagger range() as if we're creating new fields each day
            n_days = 20
            for d in range(n_days - i):
                # leave some nulls in there
                if random.randint(0, 4) == 0: continue
                # some trends, so not all scores 0.
                value = d + random.randint(-1, 1)
                created_at = datetime.datetime.today() - datetime.timedelta(days=d)
                if client:
                    fe = client.post(
                        f"/field-entries/{fid}",
                        json=dict(value=value),
                        **header
                    )
                    assert fe.status_code == 200
                    feid = fe.json()['id']
                    db.execute(text("""
                    update field_entries set created_at=:c where id=:feid 
                    """), dict(c=created_at, feid=feid))
                    db.commit()
                else:
                    db.add(M.FieldEntry(
                        field_id=fid,
                        user_id=uid,
                        value=value,
                        created_at=created_at
                    ))
                    db.commit()
Example #3
0
def sync_for(user):
    if is_dev(): return
    if not (user.habitica_user_id and user.habitica_api_token):
        return
    # https://habitica.com/apidoc/#api-Task-GetUserTasks
    logger.info("Calling Habitica")
    headers = {
        "Content-Type": "application/json",
        "x-api-user": user.habitica_user_id,
        "x-api-key": user.habitica_api_token,
        "x-client": f"{vars.HABIT_USER}-{vars.HABIT_APP}"
    }
    tasks = requests.get('https://habitica.com/api/v3/tasks/user',
                         headers=headers).json()['data']
    huser = requests.get(
        'https://habitica.com/api/v3/user?userFields=lastCron,needsCron,preferences',
        headers=headers).json()['data']

    # don't pull field if they're in the inn
    if huser['preferences']['sleep']: return

    # Use SQL to determine day, so not managing timezones in python + sql
    tz = M.User.tz(db.session, user.id)
    last_cron = db.session.execute(
        text("""
    select date(:lastCron ::timestamptz at time zone :tz)::text last_cron
    """), dict(lastCron=huser['lastCron'], tz=tz)).fetchone().last_cron

    f_map = {f.service_id: f for f in user.fields}
    t_map = {task['id']: task for task in tasks}

    # Remove Habitica-deleted tasks
    for f in user.fields:
        if f.service != 'habitica': continue
        if f.service_id not in t_map:
            db.session.delete(f)
    db.session.commit()

    # Add/update tasks from Habitica
    for task in tasks:
        # {id, text, type, value}
        # habit: {counterUp, counterDown}
        # daily:{checklist: [{completed}], completed, isDue}

        # only care about habits/dailies
        if task['type'] not in ['habit', 'daily']: continue

        f = f_map.get(task['id'], None)
        if not f:
            # Field doesn't exist here yet, add it.
            # TODO delete things here if deleted in habitica
            f = M.Field(service='habitica',
                        service_id=task['id'],
                        name=task['text'],
                        type='number')
            user.fields.append(f)
        # Text has changed on Habitica, update here
        if f.name != task['text']:
            f.name = task['text']

        db.session.commit()  # for f to have f.id

        value = 0.
        # Habit
        if task['type'] == 'habit':
            value = (task['counterUp'] or 0.) - (task['counterDown'] or 0.)
        # Daily
        else:
            value = 1. if task['completed'] \
                else 0. if not task['isDue'] \
                else -1.

            # With Checklist
            cl = task['checklist']
            if (not task['completed']) and any(c['completed'] for c in cl):
                value = sum(c['completed'] for c in cl) / len(cl)

        M.FieldEntry.upsert(db.session,
                            user_id=user.id,
                            field_id=f.id,
                            value=value,
                            day=last_cron)
        M.Field.update_avg(f.id)
        logger.info(task['text'] + " done")
Example #4
0
def sync_for(user):
    if is_dev(): return
    if not (user.habitica_user_id and user.habitica_api_token):
        return
    # https://habitica.com/apidoc/#api-Task-GetUserTasks
    logger.info("Calling Habitica")
    headers = {
        "Content-Type": "application/json",
        "x-api-user": user.habitica_user_id,
        "x-api-key": user.habitica_api_token,
        "x-client": f"{vars.HABIT_USER}-{vars.HABIT_APP}"
    }
    tasks = requests.get('https://habitica.com/api/v3/tasks/user',
                         headers=headers).json()['data']
    huser = requests.get(
        'https://habitica.com/api/v3/user?userFields=lastCron,needsCron',
        headers=headers).json()['data']

    lastCron = dparse(huser['lastCron'])
    logger.info("Habitica finished")

    fes = M.FieldEntry.get_day_entries(user.id, day=lastCron).all()

    f_map = {f.service_id: f for f in user.fields}
    fe_map = {fe.field_id: fe for fe in fes}
    t_map = {task['id']: task for task in tasks}

    # Remove Habitica-deleted tasks
    for f in user.fields:
        if f.service != 'habitica': continue
        if f.service_id not in t_map:
            db.session.delete(f)
    db.session.commit()

    # Add/update tasks from Habitica
    for task in tasks:
        # {id, text, type, value}
        # habit: {counterUp, counterDown}
        # daily:{checklist: [{completed}], completed, isDue}

        # only care about habits/dailies
        if task['type'] not in ['habit', 'daily']: continue

        f = f_map.get(task['id'], None)
        if not f:
            # Field doesn't exist here yet, add it.
            # TODO delete things here if deleted in habitica
            f = M.Field(service='habitica',
                        service_id=task['id'],
                        name=task['text'],
                        type='number')
            user.fields.append(f)
        # Text has changed on Habitica, update here
        if f.name != task['text']:
            f.name = task['text']

        db.session.commit()  # for f to have f.id

        value = 0.
        # Habit
        if task['type'] == 'habit':
            value = (task['counterUp'] or 0.) - (task['counterDown'] or 0.)
        # Daily
        else:
            value = 1. if task['completed'] \
                else 0. if not task['isDue'] \
                else -1.

            # With Checklist
            cl = task['checklist']
            if (not task['completed']) and any(c['completed'] for c in cl):
                value = sum(c['completed'] for c in cl) / len(cl)

        fe = fe_map.get(f.id, None)
        if fe:
            fe.value = value
        else:
            fe = M.FieldEntry(field_id=f.id, created_at=lastCron, value=value)
            user.field_entries.append(fe)
        db.session.commit()
        logger.info(task['text'] + " done")