telegram_bots/bots/utils.py
2022-04-10 11:51:46 +03:00

136 lines
5.1 KiB
Python

import json
from django.core import serializers
from django.core.exceptions import ImproperlyConfigured
from django.core.serializers.json import DjangoJSONEncoder
from django.http import HttpResponse
from django.views.generic import TemplateView
from bots.forms import BotForm
from bots.models import TelegramBot
from cabinet.utils import CabinetViewMixin
from config.utils import get_config_form
class BaseBotConfigView(CabinetViewMixin, TemplateView):
template_name = 'cabinet/bots/bot_form.html'
context_object_name = 'feed'
def get_queryset(self):
return TelegramBot.objects.filter(owner=self.request.user)
def get(self, request, *args, **kwargs):
self.object = self.get_object()
return self.render_to_response(self.get_context_data())
def post(self, request, *args, **kwargs):
self.object = self.get_object()
bot_form, config_form = self.get_forms()
if bot_form.is_valid() and config_form.is_valid():
return self.form_valid(bot_form, config_form)
else:
context = self.get_context_data(
forms=(bot_form, config_form)
)
return self.render_to_response(context)
def get_forms(self):
bot = self.get_object()
data = self.request.POST if self.request.method == 'POST' else None
files = self.request.FILES if self.request.method == 'POST' else None
return BotForm(data=data, files=files, instance=bot, module=self.get_content_type().model_class()), \
get_config_form(self.get_content_type().model_class())(data=data, files=files,
instance=bot.config if bot else None)
def get_context_data(self, forms=None, **kwargs):
ctx = super(BaseBotConfigView, self).get_context_data(**kwargs)
ctx['bot_form'], ctx['config_form'] = self.get_forms() if forms is None else forms
ctx['bot_module'] = model = self.model
if hasattr(model, 'form_context_data'):
bot = self.get_object()
ctx.update(model.form_context_data(self, bot.config if bot else None))
return ctx
@property
def model(self):
return self.get_content_type().model_class()
# django-braces
class AjaxResponseMixin(object):
"""
Mixin allows you to define alternative methods for ajax requests. Similar
to the normal get, post, and put methods, you can use get_ajax, post_ajax,
and put_ajax.
"""
def dispatch(self, request, *args, **kwargs):
request_method = request.method.lower()
if request.accepts("application/json") and request_method in self.http_method_names:
handler = getattr(self, "{0}_ajax".format(request_method),
self.http_method_not_allowed)
self.request = request
self.args = args
self.kwargs = kwargs
return handler(request, *args, **kwargs)
return super(AjaxResponseMixin, self).dispatch(
request, *args, **kwargs)
def get_ajax(self, request, *args, **kwargs):
return self.get(request, *args, **kwargs)
def post_ajax(self, request, *args, **kwargs):
return self.post(request, *args, **kwargs)
def put_ajax(self, request, *args, **kwargs):
return self.get(request, *args, **kwargs)
def delete_ajax(self, request, *args, **kwargs):
return self.get(request, *args, **kwargs)
class JSONResponseMixin(object):
"""
A mixin that allows you to easily serialize simple data such as a dict or
Django models.
"""
content_type = None
json_dumps_kwargs = None
json_encoder_class = DjangoJSONEncoder
def get_content_type(self):
if self.content_type is not None and not isinstance(self.content_type, str):
raise ImproperlyConfigured(
'{0} is missing a content type. Define {0}.content_type, '
'or override {0}.get_content_type().'.format(
self.__class__.__name__))
return self.content_type or "application/json"
def get_json_dumps_kwargs(self):
if self.json_dumps_kwargs is None:
self.json_dumps_kwargs = {}
self.json_dumps_kwargs.setdefault('ensure_ascii', False)
return self.json_dumps_kwargs
def render_json_response(self, context_dict, status=200):
"""
Limited serialization for shipping plain data. Do not use for models
or other complex or custom objects.
"""
json_context = json.dumps(
context_dict,
cls=self.json_encoder_class,
**self.get_json_dumps_kwargs()).encode('utf-8')
return HttpResponse(json_context,
content_type=self.get_content_type(),
status=status)
def render_json_object_response(self, objects, **kwargs):
"""
Serializes objects using Django's builtin JSON serializer. Additional
kwargs can be used the same way for django.core.serializers.serialize.
"""
json_data = serializers.serialize("json", objects, **kwargs)
return HttpResponse(json_data, content_type=self.get_content_type())