145 lines
6.0 KiB
Python
145 lines
6.0 KiB
Python
import uuid
|
|
|
|
from django.core.validators import MaxValueValidator, MinValueValidator
|
|
from django.db import models
|
|
from django.db.models.signals import post_delete
|
|
from django.db.models.signals import pre_delete
|
|
from django.dispatch import receiver
|
|
from telegram.bot import Bot
|
|
|
|
# Create your models here.
|
|
|
|
|
|
class Timestampable(models.Model):
|
|
created = models.DateTimeField(auto_now_add=True)
|
|
modified = models.DateTimeField(auto_now=True)
|
|
uuid = models.UUIDField(default=uuid.uuid4, editable=False, primary_key=False)
|
|
|
|
class Meta:
|
|
abstract = True
|
|
|
|
def __str__(self):
|
|
return repr(self)
|
|
|
|
def __repr__(self):
|
|
return f'{type(self).__name__}(**{repr(self.__dict__)})'
|
|
|
|
def on_pre_delete(self, sender, instance, **kwargs):
|
|
pass
|
|
|
|
def on_post_delete(self, sender, instance, **kwargs):
|
|
pass
|
|
|
|
|
|
@receiver(models.signals.post_delete)
|
|
def timestampable_on_post_delete(sender, instance, **kwargs):
|
|
if issubclass(sender, Timestampable):
|
|
instance.on_post_delete(sender, instance, **kwargs)
|
|
|
|
|
|
@receiver(models.signals.pre_delete)
|
|
def timestampable_on_pre_delete(sender, instance, **kwargs):
|
|
if issubclass(sender, Timestampable):
|
|
instance.on_pre_delete(sender, instance, **kwargs)
|
|
|
|
|
|
class TelegramGroup(Timestampable):
|
|
AUTO_COLLECT = True
|
|
telegram_id = models.BigIntegerField()
|
|
telegram_title = models.CharField(max_length=255)
|
|
owner = models.ForeignKey(to='TelegramUser', on_delete=models.SET_NULL, blank=False, null=True, related_name='owns')
|
|
# preferences <- GroupPreferences:group
|
|
# users_with_pending_captcha <- PendingCaptchaUser:group
|
|
# admins <- TelegramUser:admins
|
|
|
|
class Meta:
|
|
ordering = ['telegram_title', 'telegram_id']
|
|
|
|
|
|
class TelegramUser(Timestampable):
|
|
AUTO_COLLECT = True
|
|
telegram_id = models.BigIntegerField(blank=False, null=False)
|
|
telegram_first_name = models.CharField(max_length=255, blank=False, null=False)
|
|
telegram_last_name = models.CharField(max_length=255, blank=True, null=True)
|
|
telegram_username = models.CharField(max_length=255, blank=True, null=True)
|
|
admins = models.ManyToManyField(to=TelegramGroup, related_name='admins')
|
|
# login_hashes <- LoginHash:telegram_user
|
|
# pending_captchas <- PendingCaptchaUser:user
|
|
# bots <- TelegramUserBots:owner
|
|
|
|
class Meta:
|
|
ordering = ['telegram_first_name', 'telegram_id']
|
|
|
|
@property
|
|
def name(self):
|
|
return f'{self.telegram_first_name} {self.telegram_last_name or ""}'.strip()
|
|
|
|
|
|
class TelegramUserBots(Timestampable):
|
|
owner = models.ForeignKey(to=TelegramUser, on_delete=models.CASCADE, blank=False, null=False, related_name='bots')
|
|
name = models.CharField(max_length=255, blank=False, null=False)
|
|
token = models.CharField(max_length=255, blank=False, null=False)
|
|
telegram_username = models.CharField(max_length=255, blank=False, null=False)
|
|
telegram_id = models.BigIntegerField()
|
|
|
|
def on_pre_delete(self, sender, instance, **kwargs):
|
|
if instance.token is not None and instance.token != '':
|
|
Bot(instance.token).set_webhook(url='')
|
|
|
|
@property
|
|
def as_user(self):
|
|
return TelegramUser.objects.get(telegram_id=self.telegram_id)
|
|
|
|
|
|
class LoginHash(Timestampable):
|
|
AUTO_COLLECT = True
|
|
telegram_user = models.ForeignKey(to=TelegramUser, on_delete=models.CASCADE, blank=False, null=False, related_name='login_hashes')
|
|
|
|
class Meta:
|
|
ordering = ['telegram_user']
|
|
|
|
|
|
class GroupPreferences(Timestampable):
|
|
group = models.OneToOneField(to=TelegramGroup, on_delete=models.CASCADE, blank=False, null=False, related_name='preferences')
|
|
# Anti-Spam
|
|
combot_anti_spam_use = models.BooleanField(default=False, blank=True, null=False)
|
|
combot_anti_spam_leave_mess = models.BooleanField(default=False, blank=True, null=False)
|
|
combot_anti_spam_notification = models.TextField(default='', blank=True, null=False)
|
|
# Greetings
|
|
join_message = models.TextField(default='', blank=True, null=False)
|
|
leave_message = models.TextField(default='', blank=True, null=False)
|
|
# Captcha
|
|
captcha_use = models.BooleanField(default=False, blank=True, null=False)
|
|
captcha_chars = models.CharField(max_length=255, default='0123456789', blank=True, null=False)
|
|
captcha_digits = models.IntegerField(default=7, blank=True, null=False, validators=[MinValueValidator(1), MaxValueValidator(24)])
|
|
captcha_timeout = models.IntegerField(default=240, blank=True, null=False, validators=[MinValueValidator(15), MaxValueValidator(600)])
|
|
captcha_attempts = models.IntegerField(default=5, blank=True, null=False, validators=[MinValueValidator(2), MaxValueValidator(20)])
|
|
captcha_first_message = models.CharField(max_length=255, default='', blank=True, null=False)
|
|
captcha_retry_message = models.CharField(max_length=255, default='', blank=True, null=False)
|
|
captcha_leave_mess = models.BooleanField(default=False, blank=True, null=False)
|
|
captcha_generate = models.BooleanField(default=False, blank=True, null=False)
|
|
# Canned Messages
|
|
# canned_messages <- GroupCannedMessage:group_preferences
|
|
|
|
class Meta:
|
|
ordering = ['group']
|
|
|
|
|
|
class GroupCannedMessage(Timestampable):
|
|
group_preferences = models.ForeignKey(to=GroupPreferences, on_delete=models.CASCADE, blank=False, null=False, related_name='canned_messages')
|
|
listen = models.CharField(max_length=255)
|
|
reply_with = models.TextField(max_length=2000)
|
|
|
|
class Meta:
|
|
ordering = ['group_preferences', 'listen', 'reply_with']
|
|
|
|
|
|
class PendingCaptchaUser(Timestampable):
|
|
AUTO_COLLECT = True
|
|
bot_token = models.CharField(max_length=255, blank=False, null=False)
|
|
captcha_answer = models.CharField(max_length=255, blank=False, null=False)
|
|
group = models.ForeignKey(to=TelegramGroup, on_delete=models.CASCADE, related_name='users_with_pending_captcha')
|
|
user = models.ForeignKey(to=TelegramUser, on_delete=models.CASCADE, related_name='pending_captchas')
|
|
lifetime = models.IntegerField(blank=True, null=False)
|
|
attempts_left = models.IntegerField(blank=True, null=False)
|