configurable bot token

This commit is contained in:
bakatrouble 2019-01-19 09:52:00 +03:00
parent 33ff1b800b
commit 999c6af8e7
20 changed files with 154 additions and 60 deletions

View File

@ -17,6 +17,27 @@
</li>
</ul>
</nav>
{% if request.user.is_superuser %}
<hr class="separator" />
<div class="nav-subtitle">Admin</div>
<nav class="nav-main" role="navigation">
<ul class="nav nav-main">
<li class="nav-parent {% if sidebar_section %}nav-active{% endif %}">
<a href="#">
<i class="fas fa-cog" aria-hidden="true"></i>
<span>Configs</span>
</a>
<ul class="nav nav-children">
{% for slug, title in admin_configs.items %}
<li><a href="{% url 'cabinet:admin_config' slug=slug %}" class="nav-link">{{ title }}</a></li>
{% endfor %}
</ul>
</li>
</ul>
</nav>
{% endif %}
</div>
<script>

View File

@ -0,0 +1,23 @@
{% extends 'cabinet/_internal_base.html' %}
{% load bootstrap4 %}
{% block breadcrumbs %}
<li><span>Configs</span></li>
<li><span>{{ form.title }}</span></li>
{% endblock %}
{% block content %}
<form action="" method="post" class="card">
{% csrf_token %}
<header class="card-header">
<h2 class="card-title">Config</h2>
</header>
<div class="card-body">
{% bootstrap_form form layout='horizontal' %}
</div>
<footer class="card-footer text-right">
<button type="submit" class="btn btn-primary">Save</button>
</footer>
</form>
{% endblock %}

View File

@ -1,7 +1,7 @@
from django.contrib.auth.views import LogoutView
from django.urls import path, include
from cabinet.views import CabinetIndexView, LoginView
from cabinet.views import CabinetIndexView, LoginView, AdminConfigView
app_name = 'cabinet'
urlpatterns = [
@ -9,4 +9,5 @@ urlpatterns = [
path('login/', LoginView.as_view(), name='login'),
path('logout/', LogoutView.as_view(), name='logout'),
path('feeds/', include('feeds.urls', namespace='feeds')),
path('admin/config/<slug>/', AdminConfigView.as_view(), name='admin_config'),
]

View File

@ -1,3 +1,4 @@
import djconfig
from django.contrib.auth.mixins import LoginRequiredMixin
@ -13,3 +14,9 @@ class CabinetViewMixin(LoginRequiredMixin):
ctx['title'] = self.get_title()
ctx['sidebar_section'] = self.sidebar_section
return ctx
def cabinet_context_processor(ctx):
return {
'admin_configs': {form.slug: form.title for form in djconfig.config._registry},
}

View File

@ -1,5 +1,7 @@
import djconfig
from django.contrib.auth.views import LoginView as BaseLoginView
from django.views.generic import TemplateView
from django.http import Http404
from django.views.generic import TemplateView, FormView
from cabinet.utils import CabinetViewMixin
@ -23,3 +25,16 @@ class LoginView(BaseLoginView):
if not self.request.POST.get('remember'):
self.request.session.set_expiry(0)
return res
class AdminConfigView(CabinetViewMixin, FormView):
template_name = 'cabinet/admin_config.html'
def get_title(self):
return '{} config'.format(self.get_form_class().title)
def get_form_class(self):
for form in djconfig.config._registry:
if form.slug == self.kwargs.get('slug'):
return form
raise Http404()

View File

@ -2,15 +2,13 @@ import os
from celery import Celery
config = {
'broker_url': 'redis://127.0.0.1:6379/1',
}
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
app = Celery('telegram_bots')
app.config_from_object(config)
app.config_from_object({
'broker_url': 'redis://127.0.0.1:6379/1',
})
app.autodiscover_tasks()

View File

@ -26,9 +26,10 @@ INSTALLED_APPS = [
'raven.contrib.django.raven_compat',
'django_extensions',
'bootstrap4',
'djconfig',
'cabinet',
'feeds',
'cabinet.apps.CabinetConfig',
'feeds.apps.FeedsConfig',
]
MIDDLEWARE = [
@ -39,6 +40,7 @@ MIDDLEWARE = [
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'djconfig.middleware.DjConfigMiddleware',
]
ROOT_URLCONF = 'config.urls'
@ -54,7 +56,9 @@ TEMPLATES = [
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'djconfig.context_processors.config',
'config.utils.turbolinks',
'cabinet.utils.cabinet_context_processor',
],
},
},
@ -82,6 +86,19 @@ STATICFILES_FINDERS = [
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
]
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379/1",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
}
}
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "default"
PUBLIC_ROOT = BASE_DIR.path('public')
STATIC_URL = '/static/'
STATIC_ROOT = str(PUBLIC_ROOT.path('static'))

View File

@ -4,6 +4,6 @@ from django.views.generic import RedirectView
urlpatterns = [
path('', RedirectView.as_view(pattern_name='cabinet:index')),
path('admin/', admin.site.urls),
path('config/', admin.site.urls),
path('cabinet/', include('cabinet.urls', namespace='cabinet')),
]

View File

@ -1,3 +1,3 @@
DJANGO_DEBUG = False
DATABASE_URL = postgres://bots:bots@localhost/bots
SENTRY_DSN = https://
DJANGO_DEBUG=False
DATABASE_URL=postgres://bots:bots@localhost/bots
SENTRY_DSN=https://

View File

@ -3,3 +3,12 @@ from django.apps import AppConfig
class FeedsConfig(AppConfig):
name = 'feeds'
def ready(self):
self.register_config()
def register_config(self):
import djconfig
from .forms import FeedsAppConfigForm
djconfig.register(FeedsAppConfigForm)

View File

@ -1,4 +1,6 @@
from django import forms
from django.forms import ModelForm
from djconfig.forms import ConfigForm
from feeds.models import Feed
@ -19,3 +21,12 @@ def get_config_form(mdl):
model = mdl
exclude = ()
return ConfigForm
class FeedsAppConfigForm(ConfigForm):
slug = 'feeds'
title = 'Feeds'
feed_bot_token = forms.CharField(required=True)
vk_username = forms.CharField(required=True)
vk_password = forms.CharField(required=True)

View File

@ -1,15 +1,13 @@
# Generated by Django 2.1.5 on 2019-01-10 17:20
# Generated by Django 2.1.5 on 2019-01-19 05:35
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import picklefield.fields
import yamlfield.fields
class Migration(migrations.Migration):
initial = True
dependencies = [
('contenttypes', '0002_remove_content_type_name'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
@ -32,12 +30,13 @@ class Migration(migrations.Migration):
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=32)),
('chat_id', models.CharField(max_length=33)),
('check_interval', models.DurationField()),
('check_interval', models.DurationField(help_text='in seconds')),
('last_check', models.DateTimeField(blank=True, null=True)),
('last_id', picklefield.fields.PickledObjectField(blank=True, editable=False, null=True)),
('last_id', yamlfield.fields.YAMLField(blank=True, null=True)),
('config_id', models.PositiveIntegerField()),
('config_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType')),
('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
('lock', models.BooleanField(default=False)),
],
),
migrations.AlterUniqueTogether(

View File

@ -1,18 +0,0 @@
# Generated by Django 2.1.5 on 2019-01-10 18:41
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('feeds', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='feed',
name='lock',
field=models.BooleanField(default=False),
),
]

View File

@ -1,18 +0,0 @@
# Generated by Django 2.1.5 on 2019-01-19 02:49
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('feeds', '0002_feed_lock'),
]
operations = [
migrations.AlterField(
model_name='feed',
name='check_interval',
field=models.DurationField(help_text='in seconds'),
),
]

View File

@ -3,8 +3,8 @@ from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelatio
from django.contrib.contenttypes.models import ContentType
from django.db import models
from django.utils import timezone
from picklefield import PickledObjectField
from telebot import TeleBot
from yamlfield.fields import YAMLField
from feeds.tasks import execute_feed
@ -15,7 +15,7 @@ class Feed(models.Model):
chat_id = models.CharField(max_length=33)
check_interval = models.DurationField(help_text='in seconds')
last_check = models.DateTimeField(null=True, blank=True)
last_id = PickledObjectField(null=True, blank=True)
last_id = YAMLField(null=True, blank=True)
lock = models.BooleanField(default=False)
config_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)

View File

@ -1,5 +1,6 @@
from django.utils import timezone
from telebot import TeleBot
from djconfig import config
from config.celery import app
@ -15,7 +16,7 @@ def execute_feed(feed_pk):
feed.lock = True
feed.save()
bot = TeleBot('450146961:AAFcb9tyIiKAi6BHR1ZYfWuTEkYjhO3xEFE')
bot = TeleBot(config.feed_bot_token)
feed.last_id = feed.config.execute(bot, feed.chat_id, feed.last_id)
feed.last_check = timezone.now()
feed.save()

View File

@ -16,7 +16,18 @@
<h4>General options</h4>
{% bootstrap_form feed_form layout='horizontal' %}
{% if feed %}
Last check: {{ feed.last_check }}
<div class="form-group row">
<label class="col-md-3 col-form-label" for="id_feed-last_check">Last check</label>
<div class="col-md-9">
<input type="text" value="{{ feed.last_check }}" class="form-control" placeholder="Last check" title="" id="id_feed-last_check" disabled>
</div>
</div>
<div class="form-group row">
<label class="col-md-3 col-form-label" for="id_feed-last_id">Last id</label>
<div class="col-md-9">
<textarea class="form-control" placeholder="Last id" id="id_feed-last_id" disabled>{{ feed.last_id }}</textarea>
</div>
</div>
{% endif %}
<hr>
<h4>Module options</h4>

View File

@ -5,14 +5,18 @@ certifi==2018.11.29
chardet==3.0.4
Django==2.1.5
django-bootstrap4==0.0.7
django-djconfig==0.9.0
django-environ==0.4.5
django-extensions==2.1.4
django-picklefield==2.0
django-redis==4.10.0
django-yamlfield==1.0.3
enum34==1.1.6
idna==2.8
kombu==4.2.2.post1
psycopg2-binary==2.7.6.1
pyTelegramBotAPI==3.6.6
pytz==2018.9
PyYAML==3.13
raven==6.10.0
redis==3.0.1
requests==2.21.0
@ -20,4 +24,5 @@ six==1.12.0
urllib3==1.24.1
uWSGI==2.0.17.1
vine==1.2.0
vk-api==11.3.0
Werkzeug==0.14.1

View File

@ -58,3 +58,9 @@ html.dark .userbox.show .dropdown-menu a:hover {
html.dark .turbolinks-progress-bar {
background-color: #ccc;
}
html.dark .nav-subtitle {
color: #465162;
padding: 15px;
font-size: 12.8px;
font-size: 0.8rem;
}

View File

@ -61,3 +61,9 @@ html.dark
.turbolinks-progress-bar
background-color #ccc
.nav-subtitle
color: #465162
padding 15px
font-size 12.8px
font-size 0.8rem