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
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()
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")
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")