telegram_bots/bots/models.py

67 lines
2.2 KiB
Python
Raw Normal View History

2019-11-12 17:13:56 +00:00
from django.conf import settings
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
from django.contrib.contenttypes.models import ContentType
from django.db import models
2019-11-24 16:22:30 +00:00
from django.utils import timezone
2019-11-12 17:13:56 +00:00
from telegram import Bot
from telegram.ext import Dispatcher
class TelegramBot(models.Model):
owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
active = models.BooleanField(default=True)
title = models.CharField(max_length=32)
bot_token = models.CharField(max_length=256)
rpc_name = models.CharField(max_length=32, blank=True, null=True)
periodic_interval = models.DurationField(blank=True, null=True)
periodic_last_run = models.DateTimeField(blank=True, null=True)
config_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
config_id = models.PositiveIntegerField()
config = GenericForeignKey('config_type', 'config_id')
def get_bot(self):
return Bot(self.bot_token)
def build_dispatcher(self, error_handler):
2019-11-12 17:13:56 +00:00
bot = self.get_bot()
bot.get_me()
dispatcher = Dispatcher(bot, None, workers=0, use_context=True)
dispatcher.add_error_handler(error_handler)
2019-11-12 17:13:56 +00:00
self.config.build_dispatcher(dispatcher)
return dispatcher
2019-11-24 16:22:30 +00:00
def run_periodic_task(self):
if not hasattr(self.config, 'periodic_task') or not self.periodic_interval or \
(self.periodic_last_run and self.periodic_last_run > timezone.now() - self.periodic_interval):
return
self.config.periodic_task(self.get_bot())
self.periodic_last_run = timezone.now()
2019-11-12 17:13:56 +00:00
def __str__(self):
return f'#{self.pk} {self.title}'
class Meta:
unique_together = ('config_type', 'config_id')
class TelegramBotModuleConfig(models.Model):
_bot = GenericRelation(TelegramBot, content_type_field='config_type', object_id_field='config_id')
MODULE_NAME = '<Not set>'
@property
def bot(self):
return self._bot.get()
@property
def content_type(self):
return ContentType.objects.get_for_model(self.__class__)
def build_dispatcher(self, dispatcher: Dispatcher):
raise NotImplementedError()
class Meta:
abstract = True