Пример #1
0
class PerformanceRequisicao(models.Model):
    data_hora_requisicao = DateTimeFieldTz('Data/hora da requisição')
    data_hora_resposta = DateTimeFieldTz('Data/hora da resposta')
    url = models.CharField('URL', max_length=255)
    user = models.ForeignKey(User,
                             blank=True,
                             null=True,
                             on_delete=models.SET_NULL)
Пример #2
0
class PermissaoAumentoRange(models.Model):
    """Registro de permissão para aumentar range de desafio caso os desafiáveis não estejam presentes"""
    # Período de validade da permissão, em horas
    PERIODO_VALIDADE = 2
    AUMENTO_RANGE = 3

    MENSAGEM_SUCESSO_PERMISSAO_AUMENTO_RANGE = 'Permissão de aumento de range concedida com sucesso'
    MENSAGEM_ERRO_JOGADOR_IGUAL_ADMIN = 'Usuário não pode conceder permissão a si mesmo'
    MENSAGEM_ERRO_JOGADOR_JA_POSSUI_PERMISSAO_VALIDA = 'Jogador já possui permissão válida'
    MENSAGEM_ERRO_DESAFIANTE_MUITO_ABAIXO_DESAFIADO = f'Desafiante está mais de ' \
        f'{AUMENTO_RANGE + DesafioLadder.LIMITE_POSICOES_DESAFIO} posições abaixo do desafiado'
    MENSAGEM_SUCESSO_REMOCAO_PERMISSAO = 'Permissão de aumento de range removida com sucesso'
    MENSAGEM_ERRO_DESAFIO_UTILIZANDO_PERMISSAO = 'Já existe um desafio válido utilizando a permissão'

    jogador = models.ForeignKey('jogadores.Jogador',
                                on_delete=models.CASCADE,
                                related_name='permitido_aumento_range')
    admin_permissor = models.ForeignKey('jogadores.Jogador',
                                        on_delete=models.CASCADE,
                                        related_name='permissor_aumento_range')
    data_hora = DateTimeFieldTz(u'Data e hora da permissão')

    def is_valida(self, data_hora=None):
        """Define se permissão é válida na data/hora"""
        if not data_hora:
            data_hora = timezone.localtime()
        valida = (self.data_hora +
                  datetime.timedelta(hours=self.PERIODO_VALIDADE) >= data_hora)
        if valida:
            valida = (not DesafioLadder.validados.filter(
                desafiante=self.jogador,
                data_hora__gte=self.data_hora,
                data_hora__lt=data_hora).exists())

        return valida
Пример #3
0
class RemocaoJogador(models.Model):
    """Registro de remoção de jogador da ladder"""
    jogador = models.ForeignKey('jogadores.Jogador', on_delete=models.CASCADE)
    # Adicionado como datetime para facilitar comparações na hora de calcular ladder
    data = DateTimeFieldTz('Data da remoção')
    admin_removedor = models.ForeignKey('jogadores.Jogador',
                                        on_delete=models.CASCADE,
                                        related_name='admin_removedor')
    posicao_jogador = models.SmallIntegerField('Posição durante remoção')
    remocao_por_inatividade = models.BooleanField(
        'Remoção devido a inatividade?', default=False)

    class Meta():
        unique_together = ('jogador', 'data')

    def __str__(self):
        return f'{self.jogador}: {self.data}'

    def is_historico(self):
        """Define se é histórico"""
        horario_atual = timezone.localtime()
        return self.data.month != horario_atual.month or self.data.year != horario_atual.year

    @property
    def mes_ano_ladder(self):
        """Retorna mes e ano de ladder da qual remoção faz parte"""
        if self.is_historico():
            return (self.data.month, self.data.year)
        return (None, None)
Пример #4
0
class Feedback(models.Model):
    avaliador = models.ForeignKey('Jogador',
                                  on_delete=models.CASCADE,
                                  related_name='avaliador')
    avaliado = models.ForeignKey('Jogador',
                                 on_delete=models.CASCADE,
                                 related_name='avaliado')
    texto = models.CharField('Texto do feedback', max_length=250)
    data_hora = DateTimeFieldTz(u'Data e hora do feedback', auto_now_add=True)
Пример #5
0
class DecaimentoJogador(models.Model):
    """Registro de decaimento de jogador na ladder"""
    # Quantidade de dias inativo para decair
    try:
        PERIODO_INATIVIDADE = ConfiguracaoLadder.buscar_configuracao([ConfiguracaoLadder.CONFIGURACAO_PERIODO_INATIVIDADE,]) \
            [ConfiguracaoLadder.CONFIGURACAO_PERIODO_INATIVIDADE]
    except:
        PERIODO_INATIVIDADE = 30

    QTD_POSICOES_DECAIMENTO = 3  # Quantidade de posições a decair por vez

    # Permitir que primeiro decaimento seja perdoado?
    try:
        ABONAR_PRIMEIRO_DECAIMENTO = ConfiguracaoLadder.buscar_configuracao([ConfiguracaoLadder.CONFIGURACAO_ABONAR_PRIMEIRO_DECAIMENTO,]) \
            [ConfiguracaoLadder.CONFIGURACAO_ABONAR_PRIMEIRO_DECAIMENTO]
    except:
        ABONAR_PRIMEIRO_DECAIMENTO = False

    jogador = models.ForeignKey('jogadores.Jogador', on_delete=models.CASCADE)
    # Adicionado como datetime para facilitar comparações na hora de calcular ladder
    data = DateTimeFieldTz('Data do decaimento')
    posicao_inicial = models.SmallIntegerField('Posição da qual jogador caiu')
    qtd_periodos_inatividade = models.SmallIntegerField(
        'Quantidade de períodos inativo',
        validators=[MinValueValidator(1),
                    MaxValueValidator(2)])

    class Meta():
        unique_together = ('jogador', 'data')

    def __str__(self):
        return f'{self.jogador} cai de {self.posicao_inicial} em {self.data.strftime("%d/%m/%Y")}'

    @staticmethod
    def alterar_periodo_inatividade():
        DecaimentoJogador.PERIODO_INATIVIDADE = ConfiguracaoLadder.buscar_configuracao([ConfiguracaoLadder.CONFIGURACAO_PERIODO_INATIVIDADE,]) \
            [ConfiguracaoLadder.CONFIGURACAO_PERIODO_INATIVIDADE]

    @staticmethod
    def alterar_abonar_primeiro_decaimento():
        DecaimentoJogador.ABONAR_PRIMEIRO_DECAIMENTO = ConfiguracaoLadder \
            .buscar_configuracao([ConfiguracaoLadder.CONFIGURACAO_ABONAR_PRIMEIRO_DECAIMENTO,]) \
            [ConfiguracaoLadder.CONFIGURACAO_ABONAR_PRIMEIRO_DECAIMENTO]

    def is_historico(self):
        """Define se é histórico"""
        horario_atual = timezone.localtime()
        return self.data.month != horario_atual.month or self.data.year != horario_atual.year

    @property
    def mes_ano_ladder(self):
        """Retorna mes e ano de ladder da qual remoção faz parte"""
        if self.is_historico():
            return (self.data.month, self.data.year)
        return (None, None)
Пример #6
0
class HistoricoConfiguracaoLadder(models.Model):
    limite_posicoes_desafio = models.SmallIntegerField(
        'Limite de posições para desafiar', blank=True, null=True)
    melhor_de = models.SmallIntegerField('Formato melhor de',
                                         blank=True,
                                         null=True)
    periodo_season = models.SmallIntegerField('Período de uma Season',
                                              blank=True,
                                              null=True)
    abonar_primeiro_decaimento = models.BooleanField(
        'Abonar primeiro decaimento?', blank=True, null=True)
    periodo_inatividade = models.SmallIntegerField(
        'Período de inatividade para cair', blank=True, null=True)
    uso_coringa = models.BooleanField('Permitido coringa?',
                                      blank=True,
                                      null=True)
    # Guardar responsável pela alteração
    responsavel = models.ForeignKey(User,
                                    blank=True,
                                    null=True,
                                    on_delete=models.CASCADE,
                                    related_name='responsavel_alteracao')
    data_hora = DateTimeFieldTz(u'Data e hora do resultado', auto_now_add=True)
Пример #7
0
class DesafioLadder(models.Model):
    """Desafio para ladder"""
    try:
        LIMITE_POSICOES_DESAFIO = ConfiguracaoLadder.buscar_configuracao([ConfiguracaoLadder.CONFIGURACAO_LIMITE_POSICOES_DESAFIO,]) \
            [ConfiguracaoLadder.CONFIGURACAO_LIMITE_POSICOES_DESAFIO] # Diferença máxima de posições para haver desafio
    except:
        LIMITE_POSICOES_DESAFIO = 3

    # É permitido usar coringa na Ladder?
    try:
        USO_CORINGA = ConfiguracaoLadder.buscar_configuracao([ConfiguracaoLadder.CONFIGURACAO_USO_CORINGA,]) \
            [ConfiguracaoLadder.CONFIGURACAO_USO_CORINGA] # Diferença máxima de posições para haver desafio
    except:
        USO_CORINGA = True
    PERIODO_ESPERA_MESMOS_JOGADORES = 3  # Quantidade de dias a esperar para refazer um desafio
    PERIODO_ESPERA_DESAFIO_CORINGA = 60  # Quantidade de dias a esperar para utilizar um coringa

    try:
        MELHOR_DE = ConfiguracaoLadder.buscar_configuracao([ConfiguracaoLadder.CONFIGURACAO_MELHOR_DE,]) \
            [ConfiguracaoLadder.CONFIGURACAO_MELHOR_DE] # Quantidade máxima de lutas que um desafio pode ter
    except:
        MELHOR_DE = 3
    SCORE_VITORIA = ((MELHOR_DE // 2) + 1)  # Score para vitória

    MENSAGEM_ERRO_DESAFIANTE_MUITO_ABAIXO_DESAFIADO = f'Desafiante está mais de {LIMITE_POSICOES_DESAFIO} posições abaixo do desafiado'
    MENSAGEM_ERRO_DESAFIANTE_ACIMA_DESAFIADO = 'Desafiante está à frente do desafiado'
    MENSAGEM_ERRO_MESMO_JOGADOR = 'Desafiante e desafiado não podem ser o mesmo jogador'
    MENSAGEM_ERRO_PERIODO_ESPERA_MESMOS_JOGADORES = f'Desafio não respeita período mínimo de ' \
        f'{PERIODO_ESPERA_MESMOS_JOGADORES} dias entre mesmos jogadores'
    MENSAGEM_ERRO_PERIODO_ESPERA_CORINGA = f'Ainda não acabou o tempo de {PERIODO_ESPERA_DESAFIO_CORINGA} dias '\
        f'para desafiante reutilizar coringa'

    desafiante = models.ForeignKey('jogadores.Jogador',
                                   on_delete=models.CASCADE,
                                   related_name='desafiante')
    desafiado = models.ForeignKey('jogadores.Jogador',
                                  on_delete=models.CASCADE,
                                  related_name='desafiado')
    desafio_coringa = models.BooleanField(u'É desafio coringa?')
    score_desafiante = models.SmallIntegerField(
        u'Vitórias do desafiante',
        validators=[MinValueValidator(0),
                    MaxValueValidator(SCORE_VITORIA)])
    score_desafiado = models.SmallIntegerField(
        u'Vitórias do desafiado',
        validators=[MinValueValidator(0),
                    MaxValueValidator(SCORE_VITORIA)])
    admin_validador = models.ForeignKey('jogadores.Jogador',
                                        on_delete=models.CASCADE,
                                        blank=True,
                                        null=True,
                                        related_name='admin_validador')
    data_hora = DateTimeFieldTz(u'Data e hora do resultado')
    adicionado_por = models.ForeignKey('jogadores.Jogador',
                                       on_delete=models.CASCADE,
                                       related_name='criador_desafio')
    posicao_desafiante = models.SmallIntegerField(u'Posição do desafiante',
                                                  default=0)
    posicao_desafiado = models.SmallIntegerField(u'Posição do desafiado',
                                                 default=0)

    class Meta():
        unique_together = (('desafiante', 'data_hora'), ('desafiado',
                                                         'data_hora'))
        ordering = ('data_hora', )

    def __str__(self):
        return f'{self.id}: {self.data_hora}'

    @staticmethod
    def alterar_limite_posicoes_desafio():
        DesafioLadder.LIMITE_POSICOES_DESAFIO = ConfiguracaoLadder.buscar_configuracao([ConfiguracaoLadder.CONFIGURACAO_LIMITE_POSICOES_DESAFIO,]) \
            [ConfiguracaoLadder.CONFIGURACAO_LIMITE_POSICOES_DESAFIO]

        # Atualizar mensagem
        DesafioLadder.MENSAGEM_ERRO_DESAFIANTE_MUITO_ABAIXO_DESAFIADO = f'Desafiante está mais de {DesafioLadder.LIMITE_POSICOES_DESAFIO} ' \
            'posições abaixo do desafiado'

    @staticmethod
    def alterar_melhor_de():
        DesafioLadder.MELHOR_DE = ConfiguracaoLadder.buscar_configuracao([ConfiguracaoLadder.CONFIGURACAO_MELHOR_DE,]) \
            [ConfiguracaoLadder.CONFIGURACAO_MELHOR_DE]

        DesafioLadder.SCORE_VITORIA = ((DesafioLadder.MELHOR_DE // 2) + 1)

    @staticmethod
    def alterar_uso_coringa():
        DesafioLadder.USO_CORINGA = ConfiguracaoLadder.buscar_configuracao([ConfiguracaoLadder.CONFIGURACAO_USO_CORINGA,]) \
            [ConfiguracaoLadder.CONFIGURACAO_USO_CORINGA]

    @property
    def lutas(self):
        """Lista de lutas que compõe o desafio"""
        return [
            luta_ladder.luta for luta_ladder in
            self.lutaladder_set.all().select_related('luta__ganhador')
        ]

    def is_cancelado(self):
        """Define se é um desafio cancelado"""
        return hasattr(self, 'cancelamentodesafioladder')

    def is_historico(self):
        """Define se é histórico"""
        horario_atual = timezone.localtime()
        return self.data_hora.month != horario_atual.month or self.data_hora.year != horario_atual.year

    def is_validado(self):
        return self.admin_validador_id != None

    @property
    def mes_ano_ladder(self):
        """Retorna mes e ano de ladder da qual desafio faz parte"""
        if self.is_historico():
            return (self.data_hora.month, self.data_hora.year)
        return (None, None)

    @property
    def ladder(self):
        """Ladder a qual desafio se refere"""
        if self.is_historico():
            mes, ano = self.mes_ano_ladder
            return HistoricoLadder.objects.filter(ano=ano, mes=mes)
        return PosicaoLadder.objects

    def cancelavel_por_jogador(self, jogador):
        """Determina se jogador pode cancelar desafio"""
        if self.is_cancelado():
            return False
        # Admin sempre pode cancelar, criador apenas se não validado
        return jogador.admin or (not self.is_validado()
                                 and jogador == self.adicionado_por)

    def editavel_por_jogador(self, jogador):
        """Determinar se jogador pode editar desafio"""
        if self.is_cancelado():
            return False
        # Contanto que não esteja validado, jogador precisa ser admin ou criador
        return not self.is_validado() and (jogador.admin
                                           or jogador == self.adicionado_por)

    def desafiante_venceu(self):
        """Retorna se desafiante foi o ganhador"""
        return self.score_desafiante > self.score_desafiado

    def fora_da_season(self):
        """Retorna se desafio é de Season anterior"""
        season_atual = Season.objects.order_by('-data_inicio')[0]
        return self.data_hora < season_atual.data_hora_inicio

    class DesafioLadderManager(models.Manager):
        """Override do manager padrão"""
        def na_season(self, season):
            data_hora_inicio = datetime.datetime(season.data_inicio.year,
                                                 season.data_inicio.month,
                                                 season.data_inicio.day)

            # Se possui data de fim
            if season.data_fim:
                data_hora_fim = datetime.datetime(season.data_fim.year, season.data_fim.month, season.data_fim.day) \
                    + datetime.timedelta(days=1)
                return self.get_queryset().filter(data_hora__range=[
                    timezone.make_aware(data_hora_inicio),
                    timezone.make_aware(data_hora_fim,
                                        timezone.get_current_timezone())
                ])
            else:
                # Se não, buscar apenas a partir da data inicial
                return self.get_queryset().filter(
                    data_hora__gte=timezone.make_aware(data_hora_inicio))

    # Managers
    class DesafiosValidadosManager(models.Manager):
        """Manager para trazer desafios validados e não cancelados"""
        def get_queryset(self):
            return super().get_queryset().filter(
                cancelamentodesafioladder__isnull=True,
                admin_validador__isnull=False)

        def na_season(self, season):
            # Se possui data de fim
            if season.data_fim:
                data_hora_fim = datetime.datetime(season.data_fim.year, season.data_fim.month, season.data_fim.day) \
                    + datetime.timedelta(days=1)
                return self.get_queryset().filter(data_hora__range=[
                    season.data_hora_inicio,
                    timezone.make_aware(data_hora_fim)
                ])
            else:
                # Se não, buscar apenas a partir da data inicial
                return self.get_queryset().filter(
                    data_hora__gte=season.data_hora_inicio)


#     objects = models.Manager()

    objects = DesafioLadderManager()
    validados = DesafiosValidadosManager()
Пример #8
0
class RegistroTreinamento(models.Model):
    inicio = DateTimeFieldTz('Data/hora de início')
    fim = DateTimeFieldTz('Data/hora de fim')
    jogador = models.ForeignKey('jogadores.Jogador', on_delete=models.CASCADE)
Пример #9
0
class Anotacao(models.Model):
    texto = models.CharField('Texto da anotação', max_length=250)
    jogador = models.ForeignKey('jogadores.Jogador', on_delete=models.CASCADE)
    data_hora = DateTimeFieldTz('Data/hora da anotação', auto_now_add=True)
Пример #10
0
class SugestaoLadder(models.Model):
    jogador = models.ForeignKey('Jogador', on_delete=models.CASCADE)
    texto = models.CharField('Texto da sugestão', max_length=1000)
    data_hora = DateTimeFieldTz(u'Data e hora da sugestão', auto_now_add=True)