diff --git a/.deploy/deploy-dev.yaml b/.deploy/deploy-dev.yaml index 0e9f032..e1cd7fd 100644 --- a/.deploy/deploy-dev.yaml +++ b/.deploy/deploy-dev.yaml @@ -12,6 +12,8 @@ services: MONGO_PASSWORD: $MONGO_PASSWORD_DEV MINIO_HOST: "minio.develop.sprinthub.ru" MINIO_SECRET_KEY: $MINIO_SECRET_KEY_DEV + PLATFORM_SECURITY_TOKEN: $PLATFORM_SECURITY_TOKEN + STAGE: "development" networks: - net deploy: diff --git a/.deploy/deploy-prod.yaml b/.deploy/deploy-prod.yaml index 21ea660..a5d2538 100644 --- a/.deploy/deploy-prod.yaml +++ b/.deploy/deploy-prod.yaml @@ -15,6 +15,8 @@ services: MONGO_PASSWORD: $MONGO_PASSWORD_PROD MINIO_HOST: "minio.sprinthub.ru" MINIO_SECRET_KEY: $MINIO_SECRET_KEY_PROD + PLATFORM_SECURITY_TOKEN: $PLATFORM_SECURITY_TOKEN + STAGE: "production" deploy: mode: replicated restart_policy: diff --git a/bot.py b/bot.py index d59e98e..45555f3 100644 --- a/bot.py +++ b/bot.py @@ -1,4 +1,5 @@ import os +import uuid import requests import telebot @@ -6,6 +7,7 @@ from telebot.types import Message, ReplyKeyboardRemove from tools.minio import minio_client as minio from tools.mongo import mongo +from tools.sprint_platform import platform bot = telebot.TeleBot(os.getenv("TELEGRAM_TOKEN")) @@ -84,22 +86,30 @@ class Core: def handle_state_dialog(self): current_dialog = mongo.get_current_dialog(self.chat_id) chat_to_send = current_dialog['chat_id_2'] if current_dialog['chat_id_1'] == self.chat_id else current_dialog['chat_id_1'] - res = mongo.create_message(self.message.content_type, self.message_text, current_dialog['_id'], self.chat_id) + saves = platform.get_config('save') + if saves['messages']: + res = mongo.create_message(self.message.content_type, self.message_text, current_dialog['_id'], self.chat_id).inserted_id + else: + res = uuid.uuid4() if self.message.photo: - photo = requests.get(bot.get_file_url(self.message.photo[-1].file_id)).content - minio.put_object(f"photos/{res.inserted_id}.jpg", photo) + if saves['photos']: + photo = requests.get(bot.get_file_url(self.message.photo[-1].file_id)).content + minio.put_object(f"photos/{res}", photo) bot.send_photo(chat_to_send, self.message.photo[-1].file_id) if self.message.sticker: - sticker = requests.get(bot.get_file_url(self.message.sticker.file_id)).content - minio.put_object(f"stickers/{res.inserted_id}.jpg", sticker) + if saves['stickers']: + sticker = requests.get(bot.get_file_url(self.message.sticker.file_id)).content + minio.put_object(f"stickers/{res}", sticker) bot.send_sticker(chat_to_send, self.message.sticker.file_id) if self.message.voice: - voice = requests.get(bot.get_file_url(self.message.voice.file_id)).content - minio.put_object(f"voices/{res.inserted_id}.jpg", voice) + if saves['voices']: + voice = requests.get(bot.get_file_url(self.message.voice.file_id)).content + minio.put_object(f"voices/{res}", voice) bot.send_voice(chat_to_send, self.message.voice.file_id) if self.message.video_note: - video_note = requests.get(bot.get_file_url(self.message.video_note.file_id)).content - minio.put_object(f"video_notes/{res.inserted_id}.jpg", video_note) + if saves['video_notes']: + video_note = requests.get(bot.get_file_url(self.message.video_note.file_id)).content + minio.put_object(f"video_notes/{res}", video_note) bot.send_video_note(chat_to_send, self.message.video_note.file_id) self.send_message(self.message_text, chat_to_send) diff --git a/tools/mongo.py b/tools/mongo.py index 58c46fc..54e388a 100644 --- a/tools/mongo.py +++ b/tools/mongo.py @@ -16,7 +16,11 @@ class Mongo: ('state', 1) ]) self.dialogs_collection.create_index([ - ("chat_id", 1), + ("chat_id_1", 1), + ('finished_at', 1) + ]) + self.dialogs_collection.create_index([ + ("chat_id_2", 1), ('finished_at', 1) ]) diff --git a/tools/sprint_platform.py b/tools/sprint_platform.py new file mode 100644 index 0000000..4a0bd42 --- /dev/null +++ b/tools/sprint_platform.py @@ -0,0 +1,98 @@ +import json +import os +import typing +import urllib.parse +from threading import Thread +from time import sleep + +from requests import get + + +class PlatformClient: + def __init__(self, platform_security_token: str, app_name: str, stage: str, need_poll: bool = True): + self.platform_security_token = platform_security_token + self.app_name = app_name + self.stage = stage + self.endpoint = 'https://platform.sprinthub.ru/' + self.configs_url = urllib.parse.urljoin(self.endpoint, 'configs/get') + self.experiments_url = urllib.parse.urljoin(self.endpoint, 'experiments/get') + self.staff_url = urllib.parse.urljoin(self.endpoint, 'is_staff') + self.fetch_url = urllib.parse.urljoin(self.endpoint, 'fetch') + self.config_storage = {} + self.experiment_storage = {} + self.staff_storage = {} + self.poll_data() + if need_poll: + self.poll_data_in_thread() + + def poll_data_in_thread(self): + def inner(): + while True: + sleep(30) + self.fetch() + + Thread(target=inner, daemon=True).start() + + def poll_data(self): + self.fetch(with_exception=True) + + def request_with_retries(self, url, params, with_exception=False, retries_count=3): + exception_to_throw = None + for _ in range(retries_count): + try: + response = get( + url, + headers={'X-Security-Token': self.platform_security_token}, + params=params + ) + if response.status_code == 200: + return response.json() + print(f'Failed to request {url}, status_code={response.status_code}') + exception_to_throw = Exception('Not 200 status') + except Exception as exc: + print(exc) + exception_to_throw = exc + sleep(1) + print(f'Failed fetching with retries: {url}, {params}') + if with_exception: + raise exception_to_throw + + def fetch(self, with_exception=False): + if self.stage == 'local': + local_platform = json.loads(open('local_platform.json', 'r').read()) + self.config_storage = local_platform['configs'] + self.experiment_storage = local_platform['experiments'] + self.staff_storage = { + key: set(value) + for key, value in local_platform['platform_staff'].items() + } + return + response_data = self.request_with_retries(self.fetch_url, { + 'project': self.app_name, + 'stage': self.stage, + }, with_exception) + self.config_storage = response_data['configs'] + self.experiment_storage = response_data['experiments'] + self.staff_storage = { + key: set(value) + for key, value in response_data['platform_staff'].items() + } + + def is_staff(self, **kwargs): + for key, value in kwargs.items(): + if value in self.staff_storage[key]: + return True + return False + + def get_config(self, name): + return self.config_storage[name] + + def get_experiment(self, name): + return self.experiment_storage[name] + + +platform = PlatformClient( + os.getenv('PLATFORM_SECURITY_TOKEN'), + 'Ruletka', + os.getenv('STAGE', 'local') +)