cyberlina bot
This commit is contained in:
parent
61da2bd079
commit
bddcc562ba
63
bots/migrations/0009_auto_20191126_0058.py
Normal file
63
bots/migrations/0009_auto_20191126_0058.py
Normal file
@ -0,0 +1,63 @@
|
||||
# Generated by Django 3.0rc1 on 2019-11-25 21:58
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import jsonfield.encoder
|
||||
import jsonfield.fields
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('bots', '0008_auto_20191124_1922'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='CyberLinaBotModuleConfig',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('first_part', jsonfield.fields.JSONField(default=[], dump_kwargs={'cls': jsonfield.encoder.JSONEncoder, 'separators': (',', ':')}, load_kwargs={})),
|
||||
('second_part', jsonfield.fields.JSONField(default=[], dump_kwargs={'cls': jsonfield.encoder.JSONEncoder, 'separators': (',', ':')}, load_kwargs={})),
|
||||
('third_part', jsonfield.fields.JSONField(default=[], dump_kwargs={'cls': jsonfield.encoder.JSONEncoder, 'separators': (',', ':')}, load_kwargs={})),
|
||||
('emoji', jsonfield.fields.JSONField(default=[], dump_kwargs={'cls': jsonfield.encoder.JSONEncoder, 'separators': (',', ':')}, load_kwargs={})),
|
||||
('already_ran', jsonfield.fields.JSONField(default=[], dump_kwargs={'cls': jsonfield.encoder.JSONEncoder, 'separators': (',', ':')}, load_kwargs={})),
|
||||
('welcome_reactions', jsonfield.fields.JSONField(default=[], dump_kwargs={'cls': jsonfield.encoder.JSONEncoder, 'separators': (',', ':')}, load_kwargs={})),
|
||||
('inline_reactions', jsonfield.fields.JSONField(default=[], dump_kwargs={'cls': jsonfield.encoder.JSONEncoder, 'separators': (',', ':')}, load_kwargs={})),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='CyberLinaChat',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.TextField()),
|
||||
('chat_id', models.BigIntegerField(db_index=True)),
|
||||
('last_run', models.DateField(blank=True, null=True)),
|
||||
('config', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='chats', to='bots.CyberLinaBotModuleConfig')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='CyberLinaUser',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('user_id', models.BigIntegerField(db_index=True)),
|
||||
('name', models.TextField()),
|
||||
('chat', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='users', to='bots.CyberLinaChat')),
|
||||
],
|
||||
options={
|
||||
'unique_together': {('chat', 'user_id')},
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='cyberlinachat',
|
||||
name='last_choice',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='bots.CyberLinaUser'),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='cyberlinachat',
|
||||
unique_together={('config', 'chat_id')},
|
||||
),
|
||||
]
|
50
bots/migrations/0010_auto_20191126_0112.py
Normal file
50
bots/migrations/0010_auto_20191126_0112.py
Normal file
@ -0,0 +1,50 @@
|
||||
# Generated by Django 3.0rc1 on 2019-11-25 22:12
|
||||
|
||||
from django.db import migrations
|
||||
import jsonfield.encoder
|
||||
import jsonfield.fields
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('bots', '0009_auto_20191126_0058'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='cyberlinabotmoduleconfig',
|
||||
name='already_ran',
|
||||
field=jsonfield.fields.JSONField(default={'items': []}, dump_kwargs={'cls': jsonfield.encoder.JSONEncoder, 'separators': (',', ':')}, load_kwargs={}),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='cyberlinabotmoduleconfig',
|
||||
name='emoji',
|
||||
field=jsonfield.fields.JSONField(default={'items': []}, dump_kwargs={'cls': jsonfield.encoder.JSONEncoder, 'separators': (',', ':')}, load_kwargs={}),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='cyberlinabotmoduleconfig',
|
||||
name='first_part',
|
||||
field=jsonfield.fields.JSONField(default={'items': []}, dump_kwargs={'cls': jsonfield.encoder.JSONEncoder, 'separators': (',', ':')}, load_kwargs={}),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='cyberlinabotmoduleconfig',
|
||||
name='inline_reactions',
|
||||
field=jsonfield.fields.JSONField(default={'items': []}, dump_kwargs={'cls': jsonfield.encoder.JSONEncoder, 'separators': (',', ':')}, load_kwargs={}),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='cyberlinabotmoduleconfig',
|
||||
name='second_part',
|
||||
field=jsonfield.fields.JSONField(default={'items': []}, dump_kwargs={'cls': jsonfield.encoder.JSONEncoder, 'separators': (',', ':')}, load_kwargs={}),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='cyberlinabotmoduleconfig',
|
||||
name='third_part',
|
||||
field=jsonfield.fields.JSONField(default={'items': []}, dump_kwargs={'cls': jsonfield.encoder.JSONEncoder, 'separators': (',', ':')}, load_kwargs={}),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='cyberlinabotmoduleconfig',
|
||||
name='welcome_reactions',
|
||||
field=jsonfield.fields.JSONField(default={'items': []}, dump_kwargs={'cls': jsonfield.encoder.JSONEncoder, 'separators': (',', ':')}, load_kwargs={}),
|
||||
),
|
||||
]
|
50
bots/migrations/0011_auto_20191127_2117.py
Normal file
50
bots/migrations/0011_auto_20191127_2117.py
Normal file
@ -0,0 +1,50 @@
|
||||
# Generated by Django 3.0rc1 on 2019-11-27 18:17
|
||||
|
||||
from django.db import migrations
|
||||
import jsonfield.encoder
|
||||
import jsonfield.fields
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('bots', '0010_auto_20191126_0112'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='cyberlinabotmoduleconfig',
|
||||
name='already_ran',
|
||||
field=jsonfield.fields.JSONField(default='{"items": []}', dump_kwargs={'cls': jsonfield.encoder.JSONEncoder, 'separators': (',', ':')}, load_kwargs={}),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='cyberlinabotmoduleconfig',
|
||||
name='emoji',
|
||||
field=jsonfield.fields.JSONField(default='{"items": []}', dump_kwargs={'cls': jsonfield.encoder.JSONEncoder, 'separators': (',', ':')}, load_kwargs={}),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='cyberlinabotmoduleconfig',
|
||||
name='first_part',
|
||||
field=jsonfield.fields.JSONField(default='{"items": []}', dump_kwargs={'cls': jsonfield.encoder.JSONEncoder, 'separators': (',', ':')}, load_kwargs={}),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='cyberlinabotmoduleconfig',
|
||||
name='inline_reactions',
|
||||
field=jsonfield.fields.JSONField(default='{"items": []}', dump_kwargs={'cls': jsonfield.encoder.JSONEncoder, 'separators': (',', ':')}, load_kwargs={}),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='cyberlinabotmoduleconfig',
|
||||
name='second_part',
|
||||
field=jsonfield.fields.JSONField(default='{"items": []}', dump_kwargs={'cls': jsonfield.encoder.JSONEncoder, 'separators': (',', ':')}, load_kwargs={}),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='cyberlinabotmoduleconfig',
|
||||
name='third_part',
|
||||
field=jsonfield.fields.JSONField(default='{"items": []}', dump_kwargs={'cls': jsonfield.encoder.JSONEncoder, 'separators': (',', ':')}, load_kwargs={}),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='cyberlinabotmoduleconfig',
|
||||
name='welcome_reactions',
|
||||
field=jsonfield.fields.JSONField(default='{"items": []}', dump_kwargs={'cls': jsonfield.encoder.JSONEncoder, 'separators': (',', ':')}, load_kwargs={}),
|
||||
),
|
||||
]
|
@ -1,5 +1,6 @@
|
||||
from .overlay import OverlayBotModuleConfig
|
||||
from .channel_helper import ChannelHelperBotModuleConfig, QueuedItem
|
||||
from .echo import EchoBotModuleConfig
|
||||
from .cyberlina import CyberLinaBotModuleConfig
|
||||
|
||||
BOT_MODULES = [EchoBotModuleConfig, ChannelHelperBotModuleConfig, OverlayBotModuleConfig]
|
||||
BOT_MODULES = [EchoBotModuleConfig, ChannelHelperBotModuleConfig, OverlayBotModuleConfig, CyberLinaBotModuleConfig]
|
||||
|
128
bots/modules/cyberlina.py
Normal file
128
bots/modules/cyberlina.py
Normal file
@ -0,0 +1,128 @@
|
||||
import os
|
||||
from datetime import timedelta, datetime, time
|
||||
from random import choice, seed
|
||||
from uuid import uuid4
|
||||
|
||||
import humanize
|
||||
from django.db import models
|
||||
from django.utils.timezone import localdate, now, make_aware
|
||||
from jsoneditor.forms import JSONEditor
|
||||
from jsonfield import JSONField
|
||||
from telegram import Update, Chat, User, InlineQueryResultArticle, InputTextMessageContent
|
||||
from telegram.error import BadRequest
|
||||
from telegram.ext import Dispatcher, CallbackContext, MessageHandler, Filters, CommandHandler, InlineQueryHandler
|
||||
from telegram.utils.helpers import mention_html
|
||||
|
||||
from bots.models import TelegramBotModuleConfig
|
||||
|
||||
|
||||
class CyberLinaBotModuleConfig(TelegramBotModuleConfig):
|
||||
first_part = JSONField(default='{"items": []}')
|
||||
second_part = JSONField(default='{"items": []}')
|
||||
third_part = JSONField(default='{"items": []}')
|
||||
emoji = JSONField(default='{"items": []}')
|
||||
already_ran = JSONField(default='{"items": []}')
|
||||
welcome_reactions = JSONField(default='{"items": []}')
|
||||
inline_reactions = JSONField(default='{"items": []}')
|
||||
|
||||
MODULE_NAME = 'Киберлиночка'
|
||||
CUSTOM_WIDGETS = {
|
||||
'first_part': JSONEditor(),
|
||||
'second_part': JSONEditor(),
|
||||
'third_part': JSONEditor(),
|
||||
'emoji': JSONEditor(),
|
||||
'already_ran': JSONEditor(),
|
||||
'welcome_reactions': JSONEditor(),
|
||||
'inline_reactions': JSONEditor(),
|
||||
}
|
||||
|
||||
def message_handler(self, update: Update, ctx: CallbackContext):
|
||||
if not update.effective_chat or not update.effective_user:
|
||||
return
|
||||
CyberLinaUser.from_tg_obj(self, update.effective_chat, update.effective_user)
|
||||
|
||||
def goodmorning_handler(self, update: Update, ctx: CallbackContext):
|
||||
if not all([self.first_part['items'], self.second_part['items'],
|
||||
self.third_part['items'], self.emoji['items']]):
|
||||
return update.effective_message.reply_text('Я не настроена :c')
|
||||
seed(os.urandom(128))
|
||||
self.message_handler(update, ctx)
|
||||
chat = self.chats.get(chat_id=update.effective_chat.id)
|
||||
if chat.last_run and (chat.last_run >= localdate() or
|
||||
chat.last_run + timedelta(1) == localdate() and now().hour < 6):
|
||||
humanize.i18n.activate('ru_RU')
|
||||
time_left = make_aware(datetime.combine(chat.last_run + timedelta(1), time(6, 0))) - now()
|
||||
return update.effective_message.reply_text(
|
||||
choice(self.already_ran['items']).format(
|
||||
name=chat.last_choice.name,
|
||||
time=humanize.naturaldelta(time_left)
|
||||
)
|
||||
)
|
||||
while True:
|
||||
user = chat.users.order_by('?').first() # type: CyberLinaUser
|
||||
if not user:
|
||||
return update.effective_message.reply_text('Нет известных юзеров в чате')
|
||||
try:
|
||||
member = ctx.bot.get_chat_member(chat.chat_id, user.user_id)
|
||||
CyberLinaUser.from_tg_obj(self, update.effective_chat, member.user)
|
||||
break
|
||||
except BadRequest:
|
||||
user.delete()
|
||||
msg = '{}, {}! {}, {} {}'.format(
|
||||
choice(self.first_part['items']),
|
||||
choice(self.second_part['items']),
|
||||
mention_html(user.user_id, user.name),
|
||||
choice(self.third_part['items']),
|
||||
choice(self.emoji['items']),
|
||||
)
|
||||
update.effective_chat.send_message(msg, parse_mode='html')
|
||||
chat.last_run = localdate()
|
||||
chat.last_choice = user
|
||||
chat.save()
|
||||
|
||||
def inline_query_handler(self, update: Update, ctx: CallbackContext):
|
||||
if not self.inline_reactions:
|
||||
return
|
||||
seed(os.urandom(128))
|
||||
results = [
|
||||
InlineQueryResultArticle(
|
||||
id=uuid4(),
|
||||
title='Не нажимай >_<',
|
||||
input_message_content=InputTextMessageContent(choice(self.inline_reactions['items']))
|
||||
)
|
||||
]
|
||||
update.inline_query.answer(results)
|
||||
|
||||
def build_dispatcher(self, dispatcher: Dispatcher):
|
||||
dispatcher.add_handler(CommandHandler('goodmorning', self.goodmorning_handler))
|
||||
dispatcher.add_handler(MessageHandler(Filters.all, self.message_handler))
|
||||
dispatcher.add_handler(InlineQueryHandler(self.inline_query_handler))
|
||||
return dispatcher
|
||||
|
||||
|
||||
class CyberLinaChat(models.Model):
|
||||
config = models.ForeignKey(CyberLinaBotModuleConfig, on_delete=models.CASCADE, related_name='chats')
|
||||
name = models.TextField()
|
||||
chat_id = models.BigIntegerField(db_index=True)
|
||||
last_run = models.DateField(null=True, blank=True)
|
||||
last_choice = models.ForeignKey('CyberLinaUser', on_delete=models.SET_NULL, null=True, blank=True, related_name='+')
|
||||
|
||||
class Meta:
|
||||
unique_together = 'config', 'chat_id',
|
||||
|
||||
|
||||
class CyberLinaUser(models.Model):
|
||||
chat = models.ForeignKey(CyberLinaChat, on_delete=models.CASCADE, related_name='users')
|
||||
user_id = models.BigIntegerField(db_index=True)
|
||||
name = models.TextField()
|
||||
|
||||
@staticmethod
|
||||
def from_tg_obj(config: CyberLinaBotModuleConfig, chat: Chat, user: User):
|
||||
chat_title = chat.title or user.full_name
|
||||
chat, _ = CyberLinaChat.objects.update_or_create(config=config, chat_id=chat.id,
|
||||
defaults={'name': chat_title})
|
||||
CyberLinaUser.objects.update_or_create(chat=chat, user_id=user.id,
|
||||
defaults={'name': user.full_name})
|
||||
|
||||
class Meta:
|
||||
unique_together = 'chat', 'user_id',
|
@ -53,3 +53,8 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_body %}
|
||||
{{ bot_form.media }}
|
||||
{{ config_form.media }}
|
||||
{% endblock %}
|
||||
|
@ -15,6 +15,7 @@
|
||||
<link rel="stylesheet" href="{% static 'vendor/pnotify/pnotify.custom.css' %}">
|
||||
|
||||
<link rel="stylesheet" href="{% static 'css/theme.css' %}">
|
||||
<link rel="stylesheet" href="{% static 'css/skins/square-borders.css' %}">
|
||||
<link rel="stylesheet" href="{% static 'css/custom.css' %}">
|
||||
|
||||
<script src="{% static 'vendor/modernizr/modernizr.js' %}"></script>
|
||||
@ -74,5 +75,7 @@
|
||||
});
|
||||
{% endfor %}
|
||||
</script>
|
||||
|
||||
{% block extra_body %}{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
|
@ -21,6 +21,7 @@ INSTALLED_APPS = [
|
||||
'bootstrap4',
|
||||
'crispy_forms',
|
||||
'djconfig',
|
||||
'jsoneditor',
|
||||
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
@ -122,6 +123,9 @@ LOGOUT_REDIRECT_URL = LOGIN_URL
|
||||
|
||||
CRISPY_TEMPLATE_PACK = 'bootstrap4'
|
||||
|
||||
JSON_EDITOR_JS = 'https://cdnjs.cloudflare.com/ajax/libs/jsoneditor/7.0.4/jsoneditor.min.js'
|
||||
JSON_EDITOR_CSS = 'https://cdnjs.cloudflare.com/ajax/libs/jsoneditor/7.0.4/jsoneditor.min.css'
|
||||
|
||||
sentry_sdk.init(
|
||||
dsn=env.str('SENTRY_DSN', None),
|
||||
integrations=[DjangoIntegration()],
|
||||
|
@ -64,6 +64,7 @@ def get_config_form(mdl):
|
||||
class Meta:
|
||||
model = mdl
|
||||
exclude = ()
|
||||
widgets = mdl.CUSTOM_WIDGETS if hasattr(mdl, 'CUSTOM_WIDGETS') else {}
|
||||
return ConfigForm
|
||||
|
||||
|
||||
|
@ -23,6 +23,7 @@ django-djconfig==0.9.0
|
||||
django-environ==0.4.5
|
||||
django-extensions==2.1.4
|
||||
django-jet==1.0.8
|
||||
django-jsoneditor==0.1.4
|
||||
django-redis-cache==2.1.0
|
||||
django-timezone-field==3.0
|
||||
django-yamlfield==1.0.3
|
||||
@ -32,13 +33,19 @@ future==0.17.1
|
||||
h2==3.1.1
|
||||
hiredis==1.0.1
|
||||
hpack==3.0.0
|
||||
humanize==0.5.1
|
||||
hyperframe==5.2.0
|
||||
hyperlink==19.0.0
|
||||
idna==2.8
|
||||
importlib-metadata==0.23
|
||||
incremental==17.5.0
|
||||
json-rpc==1.12.1
|
||||
jsonfield2==3.0.3
|
||||
jsonschema==3.2.0
|
||||
kombu==4.2.2.post1
|
||||
more-itertools==7.2.0
|
||||
oauthlib==3.0.1
|
||||
packaging==19.2
|
||||
Pillow==5.4.1
|
||||
priority==1.3.0
|
||||
psycopg2-binary==2.7.6.1
|
||||
@ -48,7 +55,9 @@ pyasn1-modules==0.2.7
|
||||
pycparser==2.19
|
||||
PyHamcrest==1.9.0
|
||||
pyOpenSSL==19.1.0
|
||||
pyparsing==2.4.5
|
||||
Pyrogram==0.11.0
|
||||
pyrsistent==0.15.6
|
||||
PySocks==1.6.8
|
||||
pyTelegramBotAPI==3.6.6
|
||||
python-anticaptcha==0.3.1
|
||||
@ -74,4 +83,5 @@ urllib3==1.24.1
|
||||
vine==1.2.0
|
||||
vk-api==11.6.1
|
||||
Werkzeug==0.14.1
|
||||
zipp==0.6.0
|
||||
zope.interface==4.7.1
|
||||
|
@ -64,3 +64,6 @@ html.dark .nav-subtitle {
|
||||
font-size: 12.8px;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
html.dark .jsoneditor {
|
||||
background: #fff;
|
||||
}
|
||||
|
@ -67,3 +67,6 @@ html.dark
|
||||
padding 15px
|
||||
font-size 12.8px
|
||||
font-size 0.8rem
|
||||
|
||||
.jsoneditor
|
||||
background: #fff
|
||||
|
Loading…
Reference in New Issue
Block a user