コード例 #1
0
def initialize_and_update(username):
    configuration = Configuration.objects.get(user__username = username)
    day_service = DayService(user=configuration.user)
    walking_suggestion_service = WalkingSuggestionService(configuration=configuration)
    
    date_joined = day_service.get_date_at(configuration.user.date_joined)
    today = day_service.get_current_date()
    days_to_go_back = (today - date_joined).days
    date_range = [today - timedelta(days=offset+1) for offset in range(days_to_go_back)]

    while len(date_range):
        initialize_date = date_range.pop()
        try:
            walking_suggestion_service.get_initialization_days(initialize_date)
            break
        except WalkingSuggestionService.UnableToInitialize:
            pass
    
    walking_suggestion_service.initialize(initialize_date)
    NightlyUpdate.objects.filter(user = configuration.user).delete()
    
    while len(date_range):
        update_date = date_range.pop()
        walking_suggestion_service.update(update_date)
        NightlyUpdate.objects.create(
            user = configuration.user,
            day = update_date,
            updated = True
        )
コード例 #2
0
ファイル: services.py プロジェクト: kpwhri/heartsteps
 def is_forecast_in_past(self, forecast):
     day_service = DayService(user = self.__user)
     end_of_day = day_service.get_end_of_day(forecast.date)
     if end_of_day < timezone.now():
         return True
     else:
         return False
コード例 #3
0
ファイル: tasks.py プロジェクト: kpwhri/heartsteps
def export_step_count_records_csv(users, filename, start_date, end_date):
    dates_diff = end_date - start_date
    dates = [
        start_date + timedelta(days=offset)
        for offset in range(dates_diff.days)
    ]

    rows = []
    for _user in users:
        row = [_user.username]
        day_service = DayService(user=_user)
        for _date in dates:
            start = day_service.get_start_of_day(_date)
            end = start + timedelta(days=1)
            if _user.date_joined < end:
                query = StepCount.objects.filter(user=_user,
                                                 start__range=[start, end])
                row.append(query.count())
            else:
                row.append(None)
        rows.append(row)

    headers = [''] + [d.strftime('%Y-%m-%d') for d in dates]
    rows = [headers] + rows
    f = open(filename, 'w')
    writer = csv.writer(f)
    writer.writerows(rows)
    f.close()
コード例 #4
0
 def initialize(self, date=None):
     if not date:
         day_service = DayService(user=self.__user)
         date = day_service.get_current_date()
     dates = self.get_initialization_days(date)
     gap_dates = self.get_gap_days(dates)
     data = {
         'date':
         date.strftime('%Y-%m-%d'),
         'pooling':
         self.__configuration.pooling,
         'totalStepsArray': [self.get_steps(date) for date in dates],
         'preStepsMatrix': [{
             'steps': self.get_pre_steps(date)
         } for date in dates],
         'postStepsMatrix': [{
             'steps': self.get_post_steps(date)
         } for date in dates],
         'PriorAntiMatrix': [{
             'priorAnti':
             self.get_all_anti_sedentary_treatments(date)
         } for date in gap_dates],
         'DelieverMatrix': [{
             'walking': self.get_received_messages(date)
         } for date in gap_dates]
     }
     self.make_request('initialize', data=data)
     self.__configuration.service_initialized_date = date
     self.__configuration.save()
コード例 #5
0
 def get_study_day(self, time):
     day_service = DayService(user=self.__user)
     day = day_service.get_date_at(time)
     initialized_day = day_service.get_date_at(
         self.__configuration.service_initialized_date)
     difference = day - initialized_day
     return difference.days
コード例 #6
0
ファイル: services.py プロジェクト: kpwhri/heartsteps
 def localize_datetime(self, user, datetime_in_UTC):
     day_service = DayService(user)
     local_timezone = day_service.get_timezone_at(datetime_in_UTC)
     if isinstance(datetime_in_UTC, datetime):
         return datetime_in_UTC.astimezone(local_timezone)
     else:
         return datetime(datetime_in_UTC.year, datetime_in_UTC.month, datetime_in_UTC.day, tzinfo=local_timezone)
コード例 #7
0
ファイル: services.py プロジェクト: kpwhri/heartsteps
    def send_notification(self, day=False, test=False):
        if not day:
            service = DayService(user=self.__user)
            day = service.get_current_date()
        morning_message, _ = self.get_or_create(day)

        if not self.__configuration.enabled:
            raise MorningMessageService.NotEnabled()

        serialized = MorningMessageSerializer(morning_message).data
        serialized['type'] = 'morning-message'

        if not serialized['text']:
            del serialized['text']
        if not serialized['anchor']:
            del serialized['anchor']

        if serialized['notification']:
            serialized['body'] = serialized['notification']
            del serialized['notification']

        push_service = PushMessageService(user=self.__user)
        message = push_service.send_notification(
            body=morning_message.notification,
            title='Morning check-in',
            data=serialized,
            collapse_subject='morning-message',
            send_message_id_only=True)
        morning_message.add_context(message)
        return message
コード例 #8
0
ファイル: models.py プロジェクト: jup014/heartsteps
 def timezone(self):
     if hasattr(self, '_timezone'):
         return self._timezone
     service = DayService(user = self.user)
     tz = service.get_timezone_at(self.time)
     self._timezone = tz
     return self._timezone
コード例 #9
0
ファイル: models.py プロジェクト: jup014/heartsteps
 def get_study_end_datetime(self):
     study_start_date = self.get_study_start_date()
     if study_start_date and self.study_length:
         end_date = self.study_start + timedelta(days=self.study_length)
         service = DayService(user=self.user)
         return service.get_end_of_day(end_date)
     else:
         return None
コード例 #10
0
ファイル: services.py プロジェクト: kpwhri/heartsteps
 def localize_time(self, time):
     day_service = DayService(self.__user)
     local_timezone = day_service.get_timezone_at(time)
     if isinstance(time, datetime):
         return time.astimezone(local_timezone)
     else:
         return datetime(time.year, time.month, time.day, tzinfo=local_timezone)
     return time.astimezone(local_timezone)
コード例 #11
0
ファイル: tasks.py プロジェクト: kpwhri/heartsteps
def daily_update(username):
    service = ParticipantService(username=username)
    day_service = DayService(username=username)
    yesterday = day_service.get_current_date() - timedelta(days=1)
    service.update(yesterday)
    if not service.participant.study_start_date:
        service.participant.study_start_date = service.participant.get_study_start_date()
        service.participant.save()
    update_location_categories(username)
コード例 #12
0
ファイル: admin.py プロジェクト: kpwhri/heartsteps
 def daily_update(self, instance):
     if instance.daily_task:
         next_run_datetime = instance.daily_task.get_next_run_time()
         day_service = DayService(user = instance.user)
         timezone = day_service.get_timezone_at(next_run_datetime)
         corrected_datetime = next_run_datetime.astimezone(timezone)
         if next_run_datetime:
             return 'Next update at %s (%s)' % (corrected_datetime.strftime('%Y-%m-%d %H:%M'), timezone.zone)
     else:
         return 'No daily update'
コード例 #13
0
ファイル: services.py プロジェクト: kpwhri/heartsteps
    def update_weeks(self):
        service = DayService(self.__user)
        tz = service.get_current_timezone()
        now = timezone.now().astimezone(tz)
        start_date = self.__user.date_joined.astimezone(tz)

        week = self.get_or_create_week(start_date)
        while week.end < now:
            next_day = week.end + timedelta(days=1)
            week = self.get_or_create_week(next_day)
コード例 #14
0
 def update_message_receipts(self, date):
     if not self.user:
         return
     day_service = DayService(user=self.user)
     messages = PushMessage.objects.filter(
         recipient=self.user,
         created__gte=day_service.get_start_of_day(date),
         created__lte=day_service.get_end_of_day(date)).all()
     for message in messages:
         message.update_message_receipts()
コード例 #15
0
ファイル: models.py プロジェクト: jup014/heartsteps
 def get_study_start_date(self):
     if self.user and self.user.date_joined:
         study_start_datetime = self.user.date_joined
     else:
         study_start_datetime = self.get_fitbit_start_datetime()
     if study_start_datetime:
         day_service = DayService(user=self.user)
         return day_service.get_date_at(study_start_datetime)
     else:
         return None
コード例 #16
0
def activity_log_updates_day(sender, instance, *args, **kwargs):
    activity_log = instance

    day_service = DayService(user=activity_log.user)
    local_timezone = day_service.get_timezone_at(activity_log.start)
    local_time = activity_log.start.astimezone(local_timezone)
    local_date = date(local_time.year, local_time.month, local_time.day)

    for day in list_and_create_day(activity_log.user, local_date):
        day.update_from_activities()
コード例 #17
0
ファイル: models.py プロジェクト: kpwhri/heartsteps
 def __get_time_range(self, time_range):
     if time_range not in self.TIME_RANGES:
         raise RuntimeError('time range not found')
     else:
         service = DayService(user=self.user)
         today = service.get_current_date()
         start_date = today - timedelta(days=time_range.offset)
         return [
             service.get_start_of_day(start_date),
             service.get_end_of_day(today)
         ]
コード例 #18
0
ファイル: models.py プロジェクト: kpwhri/heartsteps
 def get_start_of_day(self, day=None):
     if day:
         service = DayService(user=self.user)
         day = service.get_date_at(day)
     else:
         day = self.current_datetime
     return datetime(year=day.year,
                     month=day.month,
                     day=day.day,
                     hour=self.day_start_hour,
                     minute=self.day_start_minute,
                     tzinfo=self.timezone)
コード例 #19
0
 def get_datetime_on(self, date):
     service = DayService(user = self.user)
     tz = service.get_timezone_at(date)
     local_date = service.get_date_at(date)
     dt = datetime(
         local_date.year,
         local_date.month,
         local_date.day,
         self.hour,
         self.minute
     )
     return tz.localize(dt)
コード例 #20
0
ファイル: tasks.py プロジェクト: kpwhri/heartsteps
def export_activity_logs(username,
                         filename=None,
                         directory=None,
                         start=None,
                         end=None):
    if not directory:
        directory = './'
    if not filename:
        filename = '%s.activity_logs.csv' % (username)

    activity_log_query = ActivityLog.objects.filter(
        user__username=username
    ) \
    .order_by('start') \
    .prefetch_related('type')

    day_service = DayService(username=username)
    if start:
        start_datetime = day_service.get_start_of_day(start)
        activity_log_query = activity_log_query.filter(
            start__gte=start_datetime)
    if end:
        end_datetime = day_service.get_end_of_day(end)
        activity_log_query = activity_log_query.filter(start__lte=end_datetime)

    rows = []
    headers = [
        'Participant ID', 'Activity ID', 'Study Day', 'Date', 'Start Time',
        'Timezone', 'Activity Type ID', 'Activity Type Title',
        'Activity Duration', 'Activity Vigorous'
    ]
    rows.append(headers)

    for activity_log in activity_log_query.all():
        rows.append([
            username, activity_log.id, 'study day',
            activity_log.start.astimezone(
                pytz.timezone('America/Los_Angeles')).strftime('%Y-%m-%d'),
            activity_log.start.astimezone(pytz.timezone(
                'America/Los_Angeles')).strftime('%Y-%m-%d %H:%M:%S'),
            'timezone', activity_log.type.id, activity_log.type.title,
            activity_log.duration, activity_log.vigorous
        ])

    _file = open(path.join(directory, filename), 'w')
    writer = csv.writer(_file)
    writer.writerows(rows)
    _file.close()
コード例 #21
0
ファイル: models.py プロジェクト: kpwhri/heartsteps
    def get_adherence_during(self, start, end):
        if not self.user:
            return []
        metrics = {}
        adherence_metrics = AdherenceMetric.objects.filter(
            user=self.user, date__range=[start, end]).all()
        for metric in adherence_metrics:
            if metric.date not in metrics:
                metrics[metric.date] = {}
            metrics[metric.date][metric.category] = metric.value

        messages = {}
        day_service = DayService(user=self.user)
        adherence_messages = AdherenceMessage.objects.filter(
            user=self.user,
            created__range=[
                day_service.get_start_of_day(start),
                day_service.get_end_of_day(end)
            ]).all()
        for message in adherence_messages:
            message_date = day_service.get_date(message.created)
            if message_date not in messages:
                messages[message_date] = []
            messages[message_date].append({
                'category': message.category,
                'body': message.body
            })

        summaries = []
        _dates = [
            end - timedelta(days=offset)
            for offset in range((end - start).days + 1)
        ]
        for _date in _dates:
            _metrics = {}
            if _date in metrics:
                _metrics = metrics[_date]
            _messages = []
            if _date in messages:
                _messages = messages[_date]
            summaries.append({
                'date': _date,
                'metrics': _metrics,
                'messages': _messages
            })
        return summaries
コード例 #22
0
    def suggestion_time_category_available_at(self, time):
        category = self.suggestion_time_category_at(time)
        day_service = DayService(user=self.__user)

        query = WalkingSuggestionDecision.objects.filter(
            user=self.__user,
            test=False,
            time__range=[
                day_service.get_start_of_day(time),
                day_service.get_end_of_day(time)
            ])
        tags = [decision.category for decision in query.all()]

        if category in tags:
            raise self.Unavailable('Time already taken')
        else:
            return category
コード例 #23
0
ファイル: models.py プロジェクト: kpwhri/heartsteps
 def send_message(self):
     if not self.user.is_active:
         raise Configuration.ConfigurationDisabled(
             'Configuration user disabled')
     if not self.enabled:
         raise Configuration.ConfigurationDisabled(
             'Configuration task disabled')
     if self.message:
         raise Configuration.MessageAlreadySent(
             'Will not send message twice')
     day_service = DayService(user=self.user)
     current_date = day_service.get_current_date()
     if current_date < self.closeout_date:
         raise Configuration.BeforeCloseoutDate(
             'Will not send before closeout date')
     sms_service = SMSService(user=self.user)
     self.message = sms_service.send(CLOSEOUT_MESSAGE)
     self.save()
     self.disable()
コード例 #24
0
    def test_does_not_update_if_device_sync_not_updated(self, update):
        self.configuration.service_initialized_date = date.today() - timedelta(days=1)
        self.configuration.save()
        day_service = DayService(user=self.user)

        nightly_update(
            username = self.user.username,
            day_string = date.today().strftime('%Y-%m-%d')
        )

        update.assert_not_called()
        self.assertEqual(NightlyUpdate.objects.count(), 0)
コード例 #25
0
    def decide(self, decision):
        if not self.is_initialized():
            raise self.NotInitialized()

        pooling = False
        try:
            pooling_configuration = PoolingServiceConfiguration.objects.get(
                user=self.__configuration.user)
            pooling = pooling_configuration.use_pooling
        except PoolingServiceConfiguration.DoesNotExist:
            pass

        day_service = DayService(user=decision.user)
        date = day_service.get_date_at(decision.time)

        response = self.make_request(
            'decision',
            data={
                'date':
                date.strftime('%Y-%m-%d'),
                'studyDay':
                self.get_study_day(decision.time),
                'decisionTime':
                self.categorize_suggestion_time(decision),
                'availability':
                decision.available,
                'priorAnti':
                self.anti_sedentary_treated_since_previous_decision(decision),
                'lastActivity':
                self.previous_decision_was_received(decision),
                'location':
                self.get_location_type(decision),
                'pooling':
                pooling,
                'watch':
                self.has_watch_app_step_count(decision)
            })
        decision.treated = response['send']
        decision.treatment_probability = response['probability']
        decision.save()
コード例 #26
0
ファイル: services.py プロジェクト: kpwhri/heartsteps
    def get_time_of_day_context(self):
        service = DayService(user = self.decision.user)
        local_timezone = service.get_timezone_at(self.decision.time)
        local_time = self.decision.time.astimezone(local_timezone)

        start_of_day = local_time.replace(hour=8, minute=0)
        morning_end = local_time.replace(hour=10, minute=30)
        lunch_end = local_time.replace(hour=13, minute=30)
        afternoon_end = local_time.replace(hour=16, minute=30)
        evening_end = local_time.replace(hour=18, minute=30)
        end_of_day = local_time.replace(hour=20, minute=0)

        if start_of_day < self.decision.time <= morning_end:
            return 'morning'
        if morning_end < self.decision.time <= lunch_end:
            return 'lunch'
        if lunch_end < self.decision.time <= afternoon_end:
            return 'midafternoon'
        if afternoon_end < self.decision.time <= evening_end:
            return 'evening'
        if evening_end < self.decision.time <= end_of_day:
            return 'postdinner'
コード例 #27
0
    def test_update_walking_suggestion_service(self, update):
        self.configuration.service_initialized_date = date.today() - timedelta(days=2)
        self.configuration.save()
        day_service = DayService(user=self.user)
        for _date in [date.today() - timedelta(days=offset) for offset in range(2)]:
            FitbitDay.objects.create(
                account = self.account,
                date = _date
            )
        nightly_update(
            username = self.user.username,
            day_string = date.today().strftime('%Y-%m-%d')
        )

        yesterday = date.today() - timedelta(days=1)
        update.assert_called_with(
            date = yesterday
        )
        update.assert_called_once()
        nightly_update_object = NightlyUpdate.objects.get()
        self.assertEqual(nightly_update_object.day, yesterday)
        self.assertTrue(nightly_update_object.updated)
コード例 #28
0
def export_firsts_csv(users, directory='./', filename='firsts_exports.csv'):
    headers = [[
        'HeartSteps ID', 'Enrolled Date', 'Baseline Complete Date',
        'First Anti-Sedentary Decision Date',
        'First Anti-Sedentary Decision Service Request Date',
        'First Anti-Sedentary Real-Time Sedentary Treated Decision Date'
    ]]
    rows = []
    for first in Configuration.objects.filter(user__in=users).get_firsts():
        day_service = DayService(username=first['username'])
        enroll_date = day_service.get_date_at(
            first['date_joined']) if first['date_joined'] else None
        baseline_complete_date = day_service.get_date_at(
            first['baseline_complete_date']
        ) if first['baseline_complete_date'] else None
        first_decision_date = day_service.get_date_at(
            first['first_decision'].time) if first['first_decision'] else None
        first_decision_service_request_date = day_service.get_date_at(
            first['first_decision_service_request'].request_time
        ) if first['first_decision_service_request'] else None
        first_real_time_sedentary_treated_decision_date = day_service.get_date_at(
            first['first_real_time_sedentary_treated_decision'].time
        ) if first['first_real_time_sedentary_treated_decision'] else None
        rows.append([
            first['username'],
            enroll_date.strftime('%Y-%m-%d') if enroll_date else '',
            baseline_complete_date.strftime('%Y-%m-%d')
            if baseline_complete_date else '',
            first_decision_date.strftime('%Y-%m-%d')
            if first_decision_date else '',
            first_decision_service_request_date.strftime('%Y-%m-%d')
            if first_decision_service_request_date else '',
            first_real_time_sedentary_treated_decision_date.strftime(
                '%Y-%m-%d')
            if first_real_time_sedentary_treated_decision_date else ''
        ])

    _file = open(os.path.join(directory, filename), 'w')
    writer = csv.writer(_file)
    writer.writerows(headers + rows)
    _file.close()
コード例 #29
0
ファイル: models.py プロジェクト: kpwhri/heartsteps
 def timezone(self):
     service = DayService(user=self.user)
     return service.get_current_timezone()
コード例 #30
0
ファイル: models.py プロジェクト: jup014/heartsteps
 def get_study_start_datetime(self):
     study_start_date = self.get_study_start_date()
     if study_start_date:
         day_service = DayService(user=self.user)
         return day_service.get_start_of_day(study_start_date)
     return None