from rowers.models import Alert, Condition, User, Rower, Workout from rowers.teams import coach_getcoachees from rowers.dataprep import getsmallrowdata_db,getrowdata_db import datetime ## BASIC operations # create alert def create_alert(manager, rower, measured,period=7, emailalert=True, reststrokes=False, workouttype='water', name='',**kwargs): # check if manager is coach of rower. If not return 0 if manager.rower != rower: if rower not in coach_getcoachees(manager.rower): return 0,'You are not allowed to create this alert' m = Condition( metric = measured['metric'], value1 = measured['value1'], value2 = measured['value2'], condition=measured['condition'] ) m.save() alert = Alert(name=name, manager=manager, rower=rower, measured=m, reststrokes=reststrokes, period=period, emailalert=emailalert, workouttype=workouttype ) alert.save() if 'filter' in kwargs: filters = kwargs['filter'] for f in filters: m = Condition( metric = f['metric'], value1 = f['value1'], value2 = f['value2'], condition = f['condition'] ) m.save() alert.filter.add(m) return alert.id,'Your alert was created' # update alert def alert_add_filters(alert,filter): for f in alert.filter.all(): alert.filter.remove(f) f.delete() for f in filter: m = Condition( metric = f['metric'], value1 = f['value1'], value2 = f['value2'], condition = f['condition'] ) m.save() alert.filter.add(m) return 1 # get alert stats # nperiod = 0: current period, i.e. next_run - n days to today # nperiod = 1: 1 period ago , i.e. next_run -2n days to next_run -n days def alert_get_stats(alert,nperiod=0): # get strokes workstrokesonly = not alert.reststrokes startdate = (alert.next_run - datetime.timedelta(days=(nperiod+1)*alert.period-1)) enddate = alert.next_run - datetime.timedelta(days=(nperiod)*alert.period) columns = [alert.measured.metric] for condition in alert.filter.all(): columns += condition.metric workouts = Workout.objects.filter(date__gte=startdate,date__lte=enddate,user=alert.rower, workouttype=alert.workouttype) ids = [w.id for w in workouts] df = getsmallrowdata_db(columns,ids=ids,doclean=True,workstrokesonly=workstrokesonly) if df.empty: return { 'workouts':len(workouts), 'startdate':startdate, 'enddate':enddate, 'nr_strokes':0, 'nr_strokes_qualifying':0, } # drop strokes through filter for condition in alert.filter.all(): if condition.condition == '>': mask = df[condition.metric] > condition.value1 df.loc[mask,alert.measured.metric] = np.nan elif condition.condition == '<': mask = df[condition.metric] < condition.value1 df.loc[mask,alert.measured.metric] = np.nan elif condition.condition == 'between': mask = df[condition.metric] > condition.value1 mask2 = df[condition.metric] < condition.value2 df.loc[mask & mask2,alert.measured.metric] = np.nan elif condition.condition == '=': mask = df[condition.metric] == condition.value1 df.loc[mask,alert.measured.metric] = np.nan df.dropna(inplace=True,axis=0) # count strokes nr_strokes = len(df) # count qualifying if alert.measured.condition == '>': mask = df[alert.measured.metric] > alert.measured.value1 df2 = df[mask].copy() elif alert.measured.condition == '<': mask = df[alert.measured.metric] > alert.measured.value1 df2 = df[mask].copy() elif alert.measured.condition == 'between': mask = df[alert.measured.metric] > alert.measured.value1 mask2 = df[alert.measured.metric] < alert.measured.value2 df2 = df[mask & mask2].copy() else: mask = df[alert.measured.metric] == alert.measured.value1 df2 = df[mask].copy() nr_strokes_qualifying = len(df2) return { 'workouts':len(workouts), 'startdate':startdate, 'enddate':enddate, 'nr_strokes':nr_strokes, 'nr_strokes_qualifying':nr_strokes_qualifying } # run alert report