This commit is contained in:
Administrator
2023-09-23 16:13:11 +03:00
commit 9e7fc7b4c1
605 changed files with 78660 additions and 0 deletions

7
BaseLib/BaseDaemon.py Normal file
View File

@@ -0,0 +1,7 @@
from django.core.management import BaseCommand
from BaseLib.BaseEntity import BaseEntity
class BaseDaemon(BaseCommand, BaseEntity):
...

4
BaseLib/BaseEntity.py Normal file
View File

@@ -0,0 +1,4 @@
class BaseEntity:
def get_user(self):
raise NotImplementedError

98
BaseLib/BaseView.py Normal file
View File

@@ -0,0 +1,98 @@
import typing
from django.core.handlers.wsgi import WSGIRequest
from django.http import HttpResponseRedirect, JsonResponse
from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt
from BaseLib.BaseEntity import BaseEntity
from BaseLib.bot import notify_if_needed
class AccessError(Exception):
pass
class BaseView(BaseEntity):
request: WSGIRequest
context: typing.Optional[typing.Dict] = None
required_login: typing.Optional[bool] = None
view_file: typing.Optional[str] = None
endpoint: typing.Optional[str] = None
fields_except: typing.Tuple[str] = ()
def __init__(self, request):
self.context = {}
self.request = request
def get_user(self):
return self.request.user
@classmethod
def as_path(cls):
return cls.endpoint, cls.as_view()
@classmethod
def as_view(cls):
@csrf_exempt
def execute(request: WSGIRequest):
try:
c = cls(request)
if c.required_login is not None:
if c.required_login and not request.user.is_authenticated:
return HttpResponseRedirect("/welcome")
if (
not c.required_login
and request.user.is_authenticated
):
return HttpResponseRedirect("/")
request_method = request.method.lower()
exec("from Platform.common_models import *")
context = {}
for key in request.GET.keys():
if key.endswith("_id") and key not in cls.fields_except:
model_name = key[:-3]
setattr(
c,
model_name,
eval(model_name[0].upper() + model_name[1:]).objects.get(
id=int(request.GET[key])
),
)
context[model_name] = getattr(c, model_name)
if "action" in request.POST.keys():
request_method += "_" + request.POST["action"]
method = getattr(c, request_method, None)
try:
data = c.pre_handle()
if method:
if data is None:
data = method()
if isinstance(data, BaseView):
return HttpResponseRedirect(data.endpoint)
if type(data) == str:
return HttpResponseRedirect(data)
if type(data) == dict:
return JsonResponse(data)
if data is not None:
return data
context = {**context, **c.context}
res = render(request, c.view_file, context)
res.headers["X-Frame-Options"] = "ALLOW"
return res
except AccessError:
return HttpResponseRedirect("/")
except Exception as exc:
notify_if_needed(exc)
raise
return execute
def pre_handle(self):
pass
def get(self):
pass
def post(self):
pass

0
BaseLib/__init__.py Normal file
View File

22
BaseLib/bot.py Normal file
View File

@@ -0,0 +1,22 @@
import os
import sys
import telebot
CHAT_ID = -914906133
TELEGRAM_TOKEN = os.getenv("TELEGRAM_TOKEN")
if TELEGRAM_TOKEN is not None:
bot = telebot.TeleBot(TELEGRAM_TOKEN)
def get_traceback(tb):
if tb.tb_next is not None:
next_tb = get_traceback(tb.tb_next)
else:
next_tb = ''
return str(tb.tb_frame) + '\n' + next_tb
def notify_if_needed(exc):
if type(exc) is not KeyboardInterrupt and TELEGRAM_TOKEN:
bot.send_message(CHAT_ID, f"Ошибка на проекте YourGols.\nПодробности: \n{get_traceback(sys.exc_info()[2])}\n{str(exc)}")

45
BaseLib/minio.py Normal file
View File

@@ -0,0 +1,45 @@
import io
from minio import Minio
from minio.error import MinioException
from Platform import settings
class Client:
def __init__(self, host: str, access_key: str, secret_key: str, bucket_name: str):
self.bucket_name = bucket_name
self.cli = Minio(
host,
access_key=access_key,
secret_key=secret_key,
secure=False
)
try:
self.cli.make_bucket(bucket_name)
except MinioException:
pass
def put_object(self, data: bytes, name: str):
self.cli.put_object(self.bucket_name, name, io.BytesIO(data), len(data))
def get_object(self, name: str) -> bytes:
try:
return self.cli.get_object(self.bucket_name, name).data
except MinioException:
return b""
def delete_object(self, name: str):
try:
self.cli.remove_object(self.bucket_name, name)
except MinioException:
pass
minio_client = Client(
settings.MINIO_HOST,
settings.MINIO_ACCESS_KEY,
settings.MINIO_SECRET_KEY,
settings.MINIO_BUCKET_NAME
)

96
BaseLib/queue.py Normal file
View File

@@ -0,0 +1,96 @@
import json
from json import JSONDecodeError
from time import sleep
import pika
from django import db
from BaseLib.BaseDaemon import BaseDaemon
from pika.adapters.utils.connection_workflow import AMQPConnectorException
from allinvest import settings
def blocking_connection():
return pika.BlockingConnection(
pika.ConnectionParameters(
host=settings.RABBITMQ_HOST,
credentials=pika.PlainCredentials(settings.RABBITMQ_USER, settings.RABBITMQ_PASSWORD)
)
)
def send_to_queue(routing_key, payload):
with blocking_connection() as connection:
channel = connection.channel()
queue_name = f"{settings.RABBITMQ_EXCHANGE}_{routing_key}"
channel.exchange_declare(
exchange=settings.RABBITMQ_EXCHANGE,
exchange_type='direct'
)
channel.queue_declare(queue_name)
channel.queue_bind(
exchange=settings.RABBITMQ_EXCHANGE,
queue=queue_name,
routing_key=routing_key
)
channel.basic_publish(
exchange=settings.RABBITMQ_EXCHANGE,
routing_key=routing_key,
body=json.dumps(payload).encode("UTF-8")
)
class MessagingSupport(BaseDaemon):
queue_name = None
attempts = 3
payload = dict()
def process(self):
raise NotImplementedError
def consume(self, ch, method, properties, body):
try:
data = json.loads(body.decode('utf-8'))
except JSONDecodeError:
print("Message is not JSON decodable")
return
print(f"Got {data}, processing...")
finished = False
for attempt in range(1, self.attempts + 1):
print("attempt", attempt)
try:
db.close_old_connections()
self.payload = data
self.process()
finished = True
except Exception as e:
print("failed with", str(e))
raise
sleep(1.5)
if finished:
break
if finished:
print("Process finished successfully")
else:
print("Process failed")
def handle(self, *args, **options):
if self.queue_name is None:
raise NotImplementedError("Queue name must be declared")
print("start listening " + self.queue_name)
while True:
try:
with pika.BlockingConnection(
pika.ConnectionParameters(
host=settings.RABBITMQ_HOST,
credentials=pika.PlainCredentials(settings.RABBITMQ_USER, settings.RABBITMQ_PASSWORD)
)
) as connection:
channel = connection.channel()
queue = f"{settings.RABBITMQ_EXCHANGE}_{self.queue_name}"
channel.queue_declare(queue=queue)
channel.basic_consume(queue=queue, on_message_callback=self.consume, auto_ack=True)
channel.start_consuming()
except AMQPConnectorException:
print("connection to rabbit failed: reconnecting")

30
BaseLib/redis.py Normal file
View File

@@ -0,0 +1,30 @@
import redis
from allinvest import settings
class RedisClient:
def __init__(self, host, db=1, password=None):
kwargs = {
"host": host,
"db": db
}
if password:
kwargs['password'] = password
self.cli = redis.Redis(**kwargs)
def get(self, key):
with self.cli as cli:
return cli.get(key)
def set(self, key, value):
with self.cli as cli:
cli.set(key, value)
redis_client = RedisClient(
settings.REDIS_HOST,
settings.REDIS_DB,
settings.REDIS_PASSWORD
)