Ejemplo n.º 1
0
    def test_trunc_time_func(self):
        start_datetime = microsecond_support(
            datetime(2015, 6, 15, 14, 30, 50, 321))
        end_datetime = microsecond_support(
            datetime(2016, 6, 15, 14, 10, 50, 123))
        if settings.USE_TZ:
            start_datetime = timezone.make_aware(start_datetime, is_dst=False)
            end_datetime = timezone.make_aware(end_datetime, is_dst=False)
        self.create_model(start_datetime, end_datetime)
        self.create_model(end_datetime, start_datetime)
        self.assertQuerysetEqual(
            DTModel.objects.annotate(extracted=TruncTime(
                'start_datetime')).order_by('start_datetime'), [
                    (start_datetime, start_datetime.time()),
                    (end_datetime, end_datetime.time()),
                ], lambda m: (m.start_datetime, m.extracted))
        self.assertEqual(
            DTModel.objects.filter(
                start_datetime__time=TruncTime('start_datetime')).count(), 2)

        with self.assertRaisesMessage(
                ValueError,
                "Cannot truncate DateField 'start_date' to TimeField"):
            list(DTModel.objects.annotate(truncated=TruncTime('start_date')))

        with self.assertRaisesMessage(
                ValueError,
                "Cannot truncate DateField 'start_date' to TimeField"):
            list(
                DTModel.objects.annotate(truncated=TruncTime(
                    'start_date', output_field=DateField())))
Ejemplo n.º 2
0
 def get_lecture_pending(self, instance):
     """
     Gets the lectures that are today with attendance status
     """
     today_time = datetime.datetime.now()
     today = datetime.datetime.now().date()
     lectures = Lecture.objects.filter(
         course__teacher=instance, begin__date=today,
         begin__gt=today_time).annotate(time=TruncTime('begin')).values(
             'id',
             'time',
             'course',
             code=F('course__course__code'),
             type=F('lecture_type'))
     return list(lectures)
Ejemplo n.º 3
0
 def get_lecture_pending(self, instance):
     """
     Gets the lectures that are today with attendance status
     """
     today_time = datetime.datetime.now()
     today = datetime.datetime.now().date()
     lectures = Lecture.objects.all().filter(begin__date=today,
                                             begin__gt=today_time)
     queryset = StudentsAttendLectures.objects.filter(
         student=instance, lecture__in=lectures).annotate(
             time=TruncTime('lecture__begin')).values(
                 'id',
                 'lecture',
                 'present',
                 'time',
                 course_id=F('lecture__course'),
                 code=F('lecture__course__course__code'))
     return list(queryset)
Ejemplo n.º 4
0
def change_end_date_to_end_of_day(apps, schema_editor):
    db_alias = schema_editor.connection.alias

    MeteredFeatureUnitsLog = apps.get_model('silver', 'MeteredFeatureUnitsLog')

    if MeteredFeatureUnitsLog.objects \
            .annotate(end_time=TruncTime('end_date')) \
            .filter(end_time__gte=time(0, 0, 0, 1)) \
            .exists():
        # This check should handle a reapplication of this migration after it's already been applied
        # and reverted (it works when using sqlite, might not be possible to handle on other DBs)
        return

    for mful in MeteredFeatureUnitsLog.objects.using(db_alias):
        if mful.end_date:
            mful.end_date = datetime.combine(
                mful.end_date.date(),
                datetime.max.time(),
                tzinfo=timezone.utc,
            ).replace(microsecond=0)

            mful.save(using=db_alias)
Ejemplo n.º 5
0
class Match(models.Model):
    MATCH_START_ANNOTATION = Cast(
        Func(
            TruncDate(F('match_term__day__day')),
            Value('  ', output_field=CharField()),
            TruncTime(F('match_term__start')),
            output_field=CharField(),
            function='CONCAT',
        ), output_field=DateTimeField()
    )

    objects = MatchManager()

    STATE_INIT = 'init'
    STATE_HALF_FIRST = 'half_first'
    STATE_HALF_PAUSE = 'pause'
    STATE_HALF_SECOND = 'half_second'
    STATE_END = 'end'

    STATES_CHOICES = (
        2 * (STATE_INIT,),
        2 * (STATE_HALF_FIRST,),
        2 * (STATE_HALF_PAUSE,),
        2 * (STATE_HALF_SECOND,),
        2 * (STATE_END,),
    )

    STATES = {
        STATE_INIT: (STATE_HALF_FIRST,),
        STATE_HALF_FIRST: (STATE_HALF_PAUSE,),
        STATE_HALF_PAUSE: (STATE_HALF_SECOND,),
        STATE_HALF_SECOND: (STATE_END,),
        STATE_END: ()
    }

    MATCH_PLAYING_STATE = (STATE_HALF_FIRST, STATE_HALF_PAUSE, STATE_HALF_SECOND)

    DEFAULT_STATES = (STATE_INIT, STATE_END)  # by by bool(match.confirmed)

    HALF_LENGTH = timedelta(minutes=10)

    half_length = None  # type: Optional[timedelta]

    match_term = models.ForeignKey('MatchTerm', models.PROTECT, blank=True, null=True, related_name='match_match_term')
    category = models.ForeignKey(Category, models.PROTECT, related_name='match_category')
    home_team_info = models.ForeignKey('TeamInfo', models.PROTECT, related_name='match_home_team_info')
    away_team_info = models.ForeignKey('TeamInfo', models.PROTECT, related_name='match_away_team_info')
    score_home = models.IntegerField(blank=True, null=True)
    score_away = models.IntegerField(blank=True, null=True)
    confirmed = models.DateTimeField(blank=True, null=True)
    confirmed_as = models.IntegerField(blank=True, null=True)
    online_state = models.CharField(max_length=255, choices=STATES_CHOICES, default=STATE_INIT)

    first_half_start = models.DateTimeField(blank=True, null=True)
    second_half_start = models.DateTimeField(blank=True, null=True)
    facebook_video_id = models.TextField(null=True, blank=True)

    def __str__(self):
        return _('{} vs. {}').format(self.home_team_info, self.away_team_info)

    class Meta:
        managed = False
        db_table = 'match'
        unique_together = (('category', 'home_team_info', 'away_team_info'),)
        ordering = ('match_term__day__day', 'match_term__start', 'match_term__location', 'id')

    def serialize(self, **kwargs):
        def format_color(team: "TeamInfo"):
            if team.dress_color_secondary:
                return '{t.dress_color} / {t.dress_color_secondary}'.format(t=team)
            return team.dress_color

        return dict(
            id=self.id,
            home_team_id=self.home_team_info.id,
            home_team_name=self.home_team_info.name,
            home_team_abbr=self.home_team_info.abbr or self.home_team_info.name[:4].upper(),
            home_team_slug=self.home_team_info.slug,
            home_team_color_primary=self.home_team_info.color_primary,
            home_team_color_secondary=self.home_team_info.color_secondary,
            home_team_color_text=self.home_team_info.color_text,
            home_team_color_name=format_color(self.home_team_info),

            away_team_id=self.away_team_info.id,
            away_team_name=self.away_team_info.name,
            away_team_abbr=self.away_team_info.abbr or self.away_team_info.name[:4].upper(),
            away_team_slug=self.away_team_info.slug,
            away_team_color_primary=self.away_team_info.color_primary,
            away_team_color_secondary=self.away_team_info.color_secondary,
            away_team_color_text=self.away_team_info.color_text,
            away_team_color_name=format_color(self.away_team_info),

            category_id=self.category.id,
            category_name=self.category.name,
            category_slug=self.category.slug,
            year_slug=self.category.year.slug,

            first_half_start=self.first_half_start.timestamp() if self.first_half_start else None,
            second_half_start=self.second_half_start.timestamp() if self.second_half_start else None,
            score=[self.score_home, self.score_away],
            confirmed=self.confirmed.timestamp() if self.confirmed else None,
            half_length=self.HALF_LENGTH.total_seconds() if not self.half_length else self.half_length.total_seconds(),
            state=self.online_state or (self.STATE_END if self.confirmed else self.STATE_INIT),
            facebook_video_id=self.facebook_video_id,
            match_term_start=self.match_term.timestamp,
            **kwargs
        )

    @property
    def teams(self) -> Tuple["TeamInfo", "TeamInfo"]:
        return self.home_team_info, self.away_team_info

    def change_state(self, new_state: str) -> Optional["MatchEvent"]:
        self.refresh_from_db()

        if new_state not in self.STATES:
            logging.error('MATCH {}: Unknown state {} to set.'.format(self.id, new_state))
            return

        if new_state not in self.STATES.get(self.online_state, self.DEFAULT_STATES[bool(self.confirmed)]):
            # logging.error('Cannot go from {} to {}.'.format(self.online_state, new_state))
            return

        logging.info('MATCH {}: Match state change from {} to {}.'.format(self.id, self.online_state, new_state))
        old_state = self.online_state
        self.online_state = new_state
        self.save(update_fields=('online_state',))

        event = MatchEvent(match=self)
        if not old_state or old_state == self.STATE_INIT:
            event.type = MatchEvent.TYPE_START
            event.half_index = event.time_offset = 0
            self.score_away = self.score_home = 0
            self.save(update_fields=('score_home', 'score_away',))
        elif old_state == self.STATE_HALF_FIRST:
            event.type = MatchEvent.TYPE_END
            event.half_index = 0
            event.time_offset = Match.HALF_LENGTH.total_seconds()
        elif old_state == self.STATE_HALF_PAUSE:
            event.type = MatchEvent.TYPE_START
            event.half_index = 1
            event.time_offset = 0
        elif old_state == self.STATE_HALF_SECOND:
            event.type = MatchEvent.TYPE_END
            event.half_index = 1
            event.time_offset = Match.HALF_LENGTH.total_seconds()
        else:
            raise RuntimeError('Never happen: {} -> {}.'.format(old_state, new_state))
        event.save()
        return event

    def on_timer_end(self) -> Optional['MatchEvent']:
        self.refresh_from_db()
        event = None
        if self.online_state == Match.STATE_HALF_FIRST:
            event = self.change_state(Match.STATE_HALF_PAUSE)
        elif self.online_state == Match.STATE_HALF_SECOND:
            event = self.change_state(Match.STATE_END)

        return event