This commit is contained in:
Kavalar 2024-12-06 14:20:29 +03:00
commit ae115cfbcb
38 changed files with 1178 additions and 0 deletions

4
DaHandler.py Normal file
View File

@ -0,0 +1,4 @@
class DaHandler:
def __init__(self):
pass

107
DaMsg.py Normal file
View File

@ -0,0 +1,107 @@
import emoji
class DaMsg:
def __init__(self, telegram_message):
self.telegram_message = telegram_message
self.text = self.telegram_message.text
self.caption = self.telegram_message.caption
self.stylizedText = self.telegram_message.text
self.stylizedCaption = self.telegram_message.caption
self.m = Markdown()
self.add_styles()
@staticmethod
def get_msg(data=None) -> str:
pass
def add_styles(self):
print(self.telegram_message.entities)
if self.telegram_message.entities:
self.stylizedText = self.m.add_entities_to_text(self.text, self.telegram_message.entities)
if self.telegram_message.caption_entities:
self.stylizedCaption = self.m.add_entities_to_text(self.caption, self.telegram_message.caption_entities)
class Markdown:
def __init__(self):
pass
def add_entities_to_text(self, text: str, entities_list):
offset_correction = 0
for ent in entities_list:
ent.offset += offset_correction
if ent.type == "bold":
text = self.bold(text, ent)
offset_correction += 7
if ent.type == "italic":
text = self.italic(text, ent)
offset_correction += 7
if ent.type == "underline":
text = self.underline(text, ent)
offset_correction += 7
if ent.type == "strikethrough":
text = self.strikethrough(text, ent)
offset_correction += 7
return text
@staticmethod
def bold(text: str, entities):
start = entities.offset - Markdown.get_emoji_offset(text)
text = text[:start] + "<b>" + text[start:]
end = entities.offset + entities.length - Markdown.get_emoji_offset(text) + 3
text = text[:end] + "</b>" + text[end:]
return text
@staticmethod
def italic(text: str, entities):
start = entities.offset - Markdown.get_emoji_offset(text)
text = text[:start] + "<i>" + text[start:]
end = entities.offset + entities.length - Markdown.get_emoji_offset(text) + 3
text = text[:end] + "</i>" + text[end:]
return text
@staticmethod
def underline(text: str, entities):
start = entities.offset - Markdown.get_emoji_offset(text)
text = text[:start] + "<u>" + text[start:]
end = entities.offset + entities.length - Markdown.get_emoji_offset(text) + 3
text = text[:end] + "</u>" + text[end:]
return text
@staticmethod
def strikethrough(text: str, entities):
start = entities.offset - Markdown.get_emoji_offset(text)
text = text[:start] + "<s>" + text[start:]
end = entities.offset + entities.length - Markdown.get_emoji_offset(text) + 3
text = text[:end] + "</s>" + text[end:]
return text
@staticmethod
def get_emoji_offset(text: str):
offset = 0
emoji_list = emoji.distinct_emoji_list(text)
for em in emoji_list:
if em in Markdown.exclude_slim_emoji_pool():
continue
if len(em) >= 2:
offset += 2
else:
offset += 1
return offset
@staticmethod
def exclude_slim_emoji_pool():
return [
'\u2757',
'\u2764\ufe0f',
]

235
GuildBot.py Normal file
View File

@ -0,0 +1,235 @@
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update, ReplyKeyboardMarkup, ReplyKeyboardRemove
from telegram.ext import Updater, CommandHandler, CallbackQueryHandler, ConversationHandler, MessageHandler, ChatMemberHandler, filters, ApplicationBuilder
from bot import config, text_msg_handlers, photo_msg_handlers, video_msg_handlers, da_text_msg_scenario
import re
from urllib.parse import urlparse
from bot.DaMsg import DaMsg
from datetime import datetime, timedelta
from bot.handlers.AdminActionsHandler import AdminActionsHandler
from bot.handlers.SuperAdminHandler import SuperAdminHandler
from db.models.Chat import Chat
from db.models.Booking import Booking
from db.services.ChatService import ChatService
from db.services.BookingService import BookingService
from bot.keyboards.AdminAnswerToBooking import AdminAnswerToBooking
from bot.keyboards.GetTableListKeyboard import GetTableListKeyboard
from bot.handlers.BookingHandler import BookingHandler
from bot.handlers.SetRoleHandler import SetRoleHandler
from bot.handlers.AuthHandler import AuthHandler
from bot.handlers.AdminHandler import AdminHandler
from bot.keyboards.FirstStepKeyboard import FirstStepKeyboard
from bot.msg.UserMsg import HelloMsg
from itguild_api import client
from bot.keyboards.FirstStepDeveloper import FirstStepDeveloper
from bot.keyboards.FirstStepPartner import FirstStepPartner
from bot import FIRST, SECOND, SET_EMAIL_STEP, REQUEST_CODE_STEP
class GuildBot:
def __init__(self):
self.add_new_flag = 0
self.add_photo_flag = 0
self.add_new_pool = []
self.add_photo_pool = []
self.add_video_pool = []
self.event_pool = {}
self.booking_pool = []
def run(self):
TOKEN = config['TELEGRAM_TOKEN']
application = ApplicationBuilder().token(TOKEN).build()
conv_handler = ConversationHandler(
entry_points=[
CommandHandler('start', self.start),
CommandHandler('menu', self.get_menu),
CommandHandler('show_menu', self.show_menu),
CallbackQueryHandler(AdminHandler.accept_booking, pattern='^accept=\d+$'),
CallbackQueryHandler(AdminActionsHandler.admin_respond_to_vacancy, pattern='^admin_respond_to_vacancy?\S{3,}'),
CallbackQueryHandler(AdminActionsHandler.request_sent, pattern='^request_sent?\S{3,}'),
MessageHandler(filters.TEXT, SuperAdminHandler.super_admin_text)
],
states={ # словарь состояний разговора, возвращаемых callback функциями
FIRST: [
CallbackQueryHandler(AuthHandler.request_code, pattern='^request_code'),
CallbackQueryHandler(SetRoleHandler.set_developer, pattern='^set_developer'),
MessageHandler(filters.TEXT, SuperAdminHandler.super_admin_text)
],
SECOND: [
CallbackQueryHandler(self.start_over, pattern='^start_menu'),
CallbackQueryHandler(self.thx, pattern='^thx$'),
],
SET_EMAIL_STEP: [
MessageHandler(filters.TEXT, SetRoleHandler.set_email)
],
REQUEST_CODE_STEP: [
MessageHandler(filters.TEXT, AuthHandler.add_user_at_dialog)
],
},
fallbacks=[CommandHandler('start', self.start)],
)
application.add_handler(conv_handler)
text_handler = MessageHandler(filters.TEXT & (~filters.COMMAND), self.text_msg)
application.add_handler(text_handler)
application.run_polling()
def welcome(self, update, context):
update.message.reply_text(
"""Привет. Это новостной бот канала "проСМИсь» Присылайте фото, видео, сводки и любую информацию, о которой хотите рассказать. Мы все обязательно изучим.""")
async def start(self, update, context):
# `bot.send_message` это метод Telegram API
# `update.effective_chat.id` - определяем `id` чата,
# откуда прилетело сообщение
dialog = client.tgBot.set_dialog({
'dialog_id': update.effective_chat.id,
'username': update.effective_chat.username if update.effective_chat.username else "",
'first_name': update.effective_chat.first_name if update.effective_chat.first_name else "",
'last_name': update.effective_chat.last_name if update.effective_chat.last_name else "",
})
reply_markup = FirstStepKeyboard()
print(update.effective_chat)
print(dialog)
await update.message.reply_text(HelloMsg.get_msg(), reply_markup=reply_markup.create_keyboard(), parse_mode="html")
# reaply_k = [['/start', '/menu']]
# markup = ReplyKeyboardMarkup(reaply_k, one_time_keyboard=False)
# update.message.reply_text('Пожалуйста, выберите:', reply_markup=markup)
return FIRST
def start_over(self, update, context):
"""Тот же текст и клавиатура, что и при `/start`, но не как новое сообщение"""
# Получаем `CallbackQuery` из обновления `update`
query = update.callback_query
# На запросы обратного вызова необходимо ответить,
# даже если уведомление для пользователя не требуется.
# В противном случае у некоторых клиентов могут возникнуть проблемы.
query.answer()
reply_markup = FirstStepKeyboard()
# Отредактируем сообщение, вызвавшее обратный вызов.
# Это создает ощущение интерактивного меню.
query.edit_message_text(
'Пожалуйста, выберите:', reply_markup=reply_markup.create_keyboard()
)
# Сообщаем `ConversationHandler`, что сейчас находимся в состоянии `FIRST`
return FIRST
def show_menu(self, update, context):
reply_markup = FirstStepKeyboard()
update.message.reply_text('Пожалуйста, выберите:', reply_markup=reply_markup.create_keyboard())
# context.bot.send_message(chat_id=update.effective_chat.id, text="Здесь будет меню")
return FIRST
def thx(self, update, context):
query = update.callback_query
query.answer()
query.edit_message_text(text="Спасибо!")
return ConversationHandler.END
def run_text_handlers(self, update, context):
for handler in self.get_scenario(update, context):
handler.handler(update, context)
@staticmethod
def get_last_step():
keyboard = [
[
InlineKeyboardButton("Меню", callback_data='start_menu'),
InlineKeyboardButton("Завершить", callback_data='thx')
],
]
return keyboard
@staticmethod
def get_time_variants():
time = datetime(2024, 1, 1, 15, 00)
keyboard = []
for i in range(1, 15):
keyboard.append(
[
InlineKeyboardButton(time.strftime("%H:%M"),
callback_data="set_time={time}".format(time=time.strftime("%H:%M")))
]
)
time = time + timedelta(minutes=30)
keyboard.append(
[
InlineKeyboardButton("Назад", callback_data="set_time=back")
]
)
return keyboard
@staticmethod
def get_date_to_booking():
current_day = datetime.now()
keyboard = []
for i in range(1, 8):
keyboard.append(
[
InlineKeyboardButton(current_day.strftime("%d.%m.%Y"),
callback_data="set_date={date}".format(date=current_day.strftime("%d.%m.%Y")))
]
)
current_day = current_day + timedelta(days=1)
keyboard.append(
[
InlineKeyboardButton("Назад", callback_data="set_date=back")
]
)
return keyboard
@staticmethod
def send_admins_notif(context, text, photo=None, video=None):
admins = ChatService.get_admins()
for admin in admins:
context.bot.send_message(chat_id=admin, text=text)
if photo:
context.bot.send_photo(chat_id=admin, photo=photo)
if video:
context.bot.send_video(chat_id=admin, video=video)
@staticmethod
def send_booking_notif(context, book: Booking):
admins = ChatService.get_admins()
text = "Новое бронирование:\nСтол: {table} \nДата и время: {d} \nТелефон: {p} \nПожелания: {c}".format(
table=book.table,
d=book.booking_date,
p=book.phone,
c=book.comments
)
reply_markup = AdminAnswerToBooking()
reply_markup.add_option("book_id", book.id)
for admin in admins:
context.bot.send_message(chat_id=admin.chat_id, text=text, reply_markup=reply_markup.create_keyboard())
return ConversationHandler.END
@staticmethod
def send_user_booking_notif(context, chat_id, book: Booking):
text = "Спасибо \nВаша заявка принята в обработку.\nСтол: {table} \nДата и время: {d} \nТелефон: {p} \nПожелания: {c}".format(
table=book.table,
d=book.booking_date,
p=book.phone,
c=book.comments
)
context.bot.send_message(chat_id=chat_id, text=text)

15
Handler.py Normal file
View File

@ -0,0 +1,15 @@
class Handler:
def __init__(self):
pass
@staticmethod
def load_callback_query(callback_query: str):
command, query = callback_query.split("?")
params_str = query.split("&")
params = {}
for param in params_str:
t = param.split("=")
params[t[0]] = t[1]
return [command, params]

51
HtmlMsg.py Normal file
View File

@ -0,0 +1,51 @@
import re
import emoji
class HtmlMsg:
def get_msg(self, data=None) -> str:
pass
def get_stylized_msg(self, msg):
msg = self.replace_tag_tag(msg, "p")
msg = self.replace_tag_tag(msg, "h1")
msg = self.replace_tag_tag(msg, "secure")
return msg
def replace_tag_p(self, msg: str):
msg = msg.replace("<p>", "")
msg = msg.replace("</p>", "")
return msg
def replace_tag_tag(self, msg: str, tag: str):
msg = msg.replace("<{tag}>".format(tag=tag), "")
msg = msg.replace("</{tag}>".format(tag=tag), "")
return msg
def replace_single_tag(self, msg: str, tag: str):
msg = msg.replace("<{tag}>".format(tag=tag), "")
return msg
def replace_tag_with_content(self, msg: str, tag: str):
msg = msg.replace("\r\n", "<br>")
msg = re.sub("<{tag}>.*?</{tag}>".format(tag=tag), '', msg, 0)
msg = msg.replace("<br>", "\r\n")
return msg
@staticmethod
def remove_emoji(string):
emoji_pattern = re.compile("["
u"\U0001F600-\U0001F64F" # emoticons
u"\U0001F300-\U0001F5FF" # symbols & pictographs
u"\U0001F680-\U0001F6FF" # transport & map symbols
u"\U0001F1E0-\U0001F1FF" # flags (iOS)
u"\U00002702-\U000027B0"
u"\U000024C2-\U0001F251"
"]+", flags=re.UNICODE)
return emoji_pattern.sub(r'', string)

30
Keyboard.py Normal file
View File

@ -0,0 +1,30 @@
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
class Keyboard:
def __init__(self):
self.keyboard = []
self.options = []
def get_keyboard(self):
return self.keyboard
def add_to_keyboard(self, data: InlineKeyboardButton | list):
self.keyboard.append(data)
def clear_keyboard(self):
self.keyboard = []
def create_keyboard(self):
return InlineKeyboardMarkup(self.get_keyboard())
def add_option(self, key, value):
self.options.append({key: value})
def get_option(self, key: str):
for option in self.options:
if key in option:
return option[key]
return None

53
__init__.py Normal file
View File

@ -0,0 +1,53 @@
from dotenv import dotenv_values
# from bot.handlers.MainChannelHandler import MainChannelHandler
# from bot.handlers.TestChannelHandler import TestChannelHandler
# from bot.handlers.TestChannelPhotoHandler import TestChannelPhotoHandler
# from bot.handlers.MainChannelPhotoHandler import MainChannelPhotoHandler
# from bot.handlers.TestChannelVideoHandler import TestChannelVideoHandler
# from bot.handlers.MainChannelVideoHandler import MainChannelVideoHandler
# from bot.handlers.CopyFromMainChannelHandler import CopyFromMainChannelHandler
# from bot.handlers.CopyFromMainChannelPhotoHandler import CopyFromMainChannelPhotoHandler
# from bot.handlers.CopyFromMainChannelVideoHandler import CopyFromMainChannelVideoHandler
# from bot.handlers.CopyFromTestChannelHandler import CopyFromTestChannelHandler
# from bot.handlers.TestChannelDaLinkHandler import TestChannelDaLinkHandler
# from bot.handlers.MainChannelDaLinkHandler import MainChannelDaLinkHandler
FIRST, SECOND = range(2)
SET_DATE_STEP = 3
SET_TIME_STEP = 4
SET_PHONE_STEP = 5
SET_COMMENT_STEP = 6
SET_TABLE_STEP = 7
ACCEPT_BOOKING_STEP = 8
REQUEST_CODE_STEP: int = 9
AUTH_FINISH: int = 10
BACK_STEP = 99
SET_EMAIL_STEP = 3
config = dotenv_values(".env")
text_msg_handlers = [
# MainChannelHandler(),
# TestChannelHandler(),
# CopyFromMainChannelHandler(),
# CopyFromTestChannelHandler()
]
da_text_msg_scenario = [
# MainChannelDaLinkHandler(),
# TestChannelDaLinkHandler()
]
photo_msg_handlers = [
# TestChannelPhotoHandler(),
# MainChannelPhotoHandler(),
# # CopyFromMainChannelPhotoHandler(),
# CopyFromTestChannelHandler()
]
video_msg_handlers = [
# TestChannelVideoHandler(),
# MainChannelVideoHandler(),
# # CopyFromMainChannelVideoHandler()
]

View File

@ -0,0 +1,58 @@
from bot.Handler import Handler
from telegram.constants import ParseMode
from bot import FIRST
from bot.keyboards.VacancyNotificationToAdminKeyboard import VacancyNotificationToAdminKeyboard
from bot.msg.AdminNotifMsg import AdminNotifMsg
from itguild_api import client
class AdminActionsHandler(Handler):
@staticmethod
async def admin_respond_to_vacancy(update, context):
query = update.callback_query
query.answer()
command, params = Handler.load_callback_query(query.data)
print(command, params)
admins = client.tgBot.get_admins()
recipient = client.tgBot.get_dialog(params['dialog_id'])
post = client.tgParsing.get_by_id(params['ig_post_id'])
anm = AdminNotifMsg()
for admin in admins:
if admin['status'] == 2:
reply_markup = VacancyNotificationToAdminKeyboard()
reply_markup.add_option("post", post)
reply_markup.add_option("recipient", admin)
msg = anm.get_msg({'admin': admin, 'post': post, 'recipient': recipient, 'recipient_respond': True})
await context.bot.send_message(chat_id=admin['dialog_id'], text=msg, parse_mode=ParseMode.HTML, reply_markup=reply_markup.create_keyboard())
await context.bot.send_message(chat_id=update.effective_chat.id, text="<b>Отклик отправлен</b>", parse_mode=ParseMode.HTML)
return FIRST
@staticmethod
async def request_sent(update, context):
query = update.callback_query
# query.answer()
data = query.data
command, params = Handler.load_callback_query(data)
user = client.tgBot.get_dialog(update.effective_chat.id)
post = client.tgParsing.get_by_id(params['ig_post_id'])
reply_markup = VacancyNotificationToAdminKeyboard()
reply_markup.add_option("post", post)
reply_markup.add_option("recipient", user)
client.tgParsing.update({'id': int(post['id']), 'status': 5})
post['status'] = 5
msg = AdminNotifMsg()
text = msg.get_msg({"post": post, "admin": user, "status": "Запрос отправлен"})
await query.edit_message_text(text=text, parse_mode=ParseMode.HTML, reply_markup=reply_markup.create_keyboard())
return FIRST

36
handlers/AdminHandler.py Normal file
View File

@ -0,0 +1,36 @@
from bot.Handler import Handler
from db.services.BookingService import BookingService
from db.services.ChatService import ChatService
from bot import FIRST
class AdminHandler(Handler):
@staticmethod
def accept_booking(update, context):
query = update.callback_query
query.answer()
variant = query.data
command, book_id = variant.split("=")
book = BookingService.get_booking_by_id(book_id)
BookingService.edit(book, "status", BookingService.STATUS_ACCEPTED)
context.bot.send_message(chat_id=book.chat_id, text="Администратор принял заявку")
admin = ChatService.get_by_chat_id(update.effective_chat.id)
name = "Неизвестный"
if hasattr(admin, "username"):
name = admin.username
elif hasattr(admin, "first_name"):
name = admin.first_name
admins = ChatService.get_admins()
for admin in admins:
context.bot.send_message(chat_id=admin.chat_id,
text="Администратор {name} принял заявку.".format(name=name))
return FIRST

35
handlers/AuthHandler.py Normal file
View File

@ -0,0 +1,35 @@
from bot.Handler import Handler
from bot import SET_DATE_STEP, SET_TABLE_STEP, REQUEST_CODE_STEP, FIRST, AUTH_FINISH, config
from bot.keyboards.DateToBookingKeyboard import DateToBookingKeyboard
from bot.keyboards.FirstStepKeyboard import FirstStepKeyboard
from bot.keyboards.GetTableListKeyboard import GetTableListKeyboard
from itguild_api import client
from bot.DaMsg import DaMsg
class AuthHandler(Handler):
@staticmethod
async def request_code(update, context):
await context.bot.send_message(chat_id=update.effective_chat.id, text="Введите код:")
return REQUEST_CODE_STEP
@staticmethod
async def add_user_at_dialog(update, context):
msg = DaMsg(update.effective_message)
user = client.tgBot.get_user({'token': msg.text})
if "error" in user:
reply_markup = FirstStepKeyboard()
await context.bot.send_message(chat_id=update.effective_chat.id,
text="Пользователь не найден. Проверте верность введенного кода.",
reply_markup=reply_markup.create_keyboard())
else:
dialog = client.tgBot.set_user_at_dialog({'dialog_id': update.effective_chat.id, 'user_id': user['id']})
await context.bot.send_message(chat_id=update.effective_chat.id,
text="Авторизация прошла успешно.")
print(user)
return FIRST

View File

@ -0,0 +1,31 @@
from bot.Handler import Handler
from bot import SET_DATE_STEP, SET_TABLE_STEP
from bot.keyboards.DateToBookingKeyboard import DateToBookingKeyboard
from bot.keyboards.GetTableListKeyboard import GetTableListKeyboard
class BookingHandler(Handler):
@staticmethod
def booking_vip(update, context):
query = update.callback_query
query.answer()
reply_markup = DateToBookingKeyboard()
query.edit_message_text(
'Выберите удобную дату:', reply_markup=reply_markup.create_keyboard()
)
return SET_DATE_STEP
@staticmethod
def booking_table(update, context):
query = update.callback_query
query.answer()
reply_markup = GetTableListKeyboard()
query.edit_message_text(
'Выберите удобный стол:', reply_markup=reply_markup.create_keyboard()
)
return SET_TABLE_STEP

View File

@ -0,0 +1,13 @@
from bot.DaHandler import DaHandler
from telegram import ParseMode
import bot
class CopyFromMainChannelHandler(DaHandler):
def handler(self, update, context):
if bot.config['MAIN_CANNEL_ID'] == str(update.effective_chat.id):
text = "{text} \n\n {bot_link}".format(text=update.effective_message.text,
bot_link="&#128073; <a href='https://t.me/prosmi_bot'>Предложить новость</a>")
context.bot.send_message(chat_id=bot.config['NEW_MAIN_CHANNEL_ID'], text=text, parse_mode=ParseMode.HTML)

View File

@ -0,0 +1,14 @@
from bot.DaHandler import DaHandler
from telegram import ParseMode
import bot
class CopyFromMainChannelPhotoHandler(DaHandler):
def handler(self, update, context):
if bot.config['MAIN_CANNEL_ID'] == str(update.effective_chat.id):
if update.effective_message.caption is not None:
text = "{text} \n\n {bot_link}".format(text=update.effective_message.caption,
bot_link="&#128073; <a href='https://t.me/prosmi_bot'>Предложить новость</a>")
context.bot.send_message(chat_id=bot.config['NEW_MAIN_CHANNEL_ID'], text=text, parse_mode=ParseMode.HTML)

View File

@ -0,0 +1,14 @@
from bot.DaHandler import DaHandler
from telegram import ParseMode
import bot
class CopyFromMainChannelVideoHandler(DaHandler):
def handler(self, update, context):
if bot.config['TEST_CHANNEL_ID'] == str(update.effective_chat.id):
if update.effective_message.caption is not None:
text = "{text} \n\n {bot_link}".format(text=update.effective_message.caption,
bot_link="&#128073; <a href='https://t.me/prosmi_bot'>Предложить новость</a>")
context.bot.send_message(chat_id=bot.config['NEW_MAIN_CHANNEL_ID'], text=text, parse_mode=ParseMode.HTML)

View File

@ -0,0 +1,15 @@
from bot.DaHandler import DaHandler
from telegram import ParseMode
import bot
class CopyFromTestChannelHandler(DaHandler):
def handler(self, update, context):
if bot.config['TEST_CHANNEL_ID'] == str(update.effective_chat.id):
print(update)
print(context)
context.bot.copy_message(from_chat_id=update.effective_chat.id,
chat_id=1078162189,
message_id=update.effective_message.message_id,
parse_mode=ParseMode.HTML)

View File

@ -0,0 +1,25 @@
from bot.DaHandler import DaHandler
from telegram import ParseMode
import bot
import re
from urllib.parse import urlparse
class MainChannelDaLinkHandler(DaHandler):
def handler(self, update, context):
if bot.config['MAIN_CANNEL_ID'] == str(update.effective_chat.id):
if update.effective_message.text is not None:
text = update.effective_message.text
s = re.search("(?P<url>https?://[^\s]+)", text)
if s is not None:
link = s.group("url")
domain = urlparse(link).netloc
if domain == bot.config['MAP_DOMAIN']:
final_text = "{text}".format(
text="<a href='{link}'>&#128506; Смотреть на карте</a>".format(link=link))
update.effective_message.text = final_text
context.bot.editMessageText(chat_id=update.effective_chat.id,
message_id=update.effective_message.message_id,
text=final_text, parse_mode=ParseMode.HTML)

View File

@ -0,0 +1,17 @@
from bot.DaHandler import DaHandler
from telegram import ParseMode
import bot
from bot.DaMsg import DaMsg
class MainChannelHandler(DaHandler):
def handler(self, update, context):
if bot.config['MAIN_CANNEL_ID'] == str(update.effective_chat.id):
da_msg = DaMsg(update.effective_message)
text = "{text} \n\n {bot_link}".format(text=da_msg.stylizedText,
bot_link="&#128073; <a href='https://t.me/prosmi_bot'>Предложить новость</a>")
context.bot.editMessageText(chat_id=update.effective_chat.id,
message_id=update.effective_message.message_id,
text=text, parse_mode=ParseMode.HTML)

View File

@ -0,0 +1,18 @@
from bot.DaHandler import DaHandler
from telegram import ParseMode
import bot
from bot.DaMsg import DaMsg
class MainChannelPhotoHandler(DaHandler):
def handler(self, update, context):
if bot.config['MAIN_CANNEL_ID'] == str(update.effective_chat.id):
if update.effective_message.caption is not None:
da_msg = DaMsg(update.effective_message)
text = "{text} \n\n {bot_link}".format(text=da_msg.stylizedCaption,
bot_link="&#128073; <a href='https://t.me/prosmi_bot'>Предложить новость</a>")
context.bot.editMessageCaption(chat_id=update.effective_chat.id,
message_id=update.effective_message.message_id,
caption=text, parse_mode=ParseMode.HTML)

View File

@ -0,0 +1,16 @@
from bot.DaHandler import DaHandler
from telegram import ParseMode
import bot
class MainChannelVideoHandler(DaHandler):
def handler(self, update, context):
if bot.config['MAIN_CANNEL_ID'] == str(update.effective_chat.id):
if update.effective_message.caption is not None:
text = "{text} \n\n {bot_link}".format(text=update.effective_message.caption,
bot_link="&#128073; <a href='https://t.me/prosmi_bot'>Предложить новость</a>")
context.bot.editMessageCaption(chat_id=update.effective_chat.id,
message_id=update.effective_message.message_id,
caption=text, parse_mode=ParseMode.HTML)

View File

@ -0,0 +1,40 @@
from bot.Handler import Handler
from db.services.ChatService import ChatService
from bot import SET_EMAIL_STEP
from bot.DaMsg import DaMsg
from bot.msg.SetEmailMsg import SetEmailMsg
class SetRoleHandler(Handler):
@staticmethod
async def set_partner(update, context):
chat = ChatService.get_by_chat_id(update.effective_chat.id)
ChatService.edit(chat, "status", 20)
msg = SetEmailMsg(update.effective_message)
await context.bot.send_message(chat_id=update.effective_chat.id, text=msg.get_msg())
return SET_EMAIL_STEP
@staticmethod
async def set_developer(update, context):
chat = ChatService.get_by_chat_id(update.effective_chat.id)
ChatService.edit(chat, "status", 10)
msg = SetEmailMsg(update.effective_message)
await context.bot.send_message(chat_id=update.effective_chat.id, text=msg.get_msg())
return SET_EMAIL_STEP
@staticmethod
async def set_email(update, context):
chat = ChatService.get_by_chat_id(update.effective_chat.id)
msg = DaMsg(update.effective_message)
ChatService.edit(chat, "email", msg.text)
await context.bot.send_message(chat_id=update.effective_chat.id, text="Спасибо)")
return SET_EMAIL_STEP

View File

@ -0,0 +1,16 @@
from bot.DaMsg import DaMsg
from bot.Handler import Handler
from bot import config, FIRST
from itguild_api import client
class SuperAdminHandler(Handler):
@staticmethod
async def super_admin_text(update, context):
if int(update.effective_chat.id) == int(config['SUPER_ADMINS']):
all = client.tgBot.get_all()
for user in all:
if int(user['dialog_id']) != int(config['SUPER_ADMINS']):
await context.bot.send_message(chat_id=user['dialog_id'], text=update.effective_message.text)
return FIRST

View File

@ -0,0 +1,25 @@
from bot.DaHandler import DaHandler
from telegram import ParseMode
import bot
import re
from urllib.parse import urlparse
class TestChannelDaLinkHandler(DaHandler):
def handler(self, update, context):
if bot.config['TEST_CHANNEL_ID'] == str(update.effective_chat.id):
if update.effective_message.text is not None:
text = update.effective_message.text
s = re.search("(?P<url>https?://[^\s]+)", text)
if s is not None:
link = s.group("url")
domain = urlparse(link).netloc
if domain == bot.config['MAP_DOMAIN']:
final_text = "{text}".format(
text="<a href='{link}'>&#128506; Смотреть на карте</a>".format(link=link))
update.effective_message.text = final_text
context.bot.editMessageText(chat_id=update.effective_chat.id,
message_id=update.effective_message.message_id,
text=final_text, parse_mode=ParseMode.HTML)

View File

@ -0,0 +1,19 @@
import emoji
from bot.DaHandler import DaHandler
from telegram import ParseMode
import bot
from bot.DaMsg import DaMsg
class TestChannelHandler(DaHandler):
def handler(self, update, context):
if bot.config['TEST_CHANNEL_ID'] == str(update.effective_chat.id):
da_msg = DaMsg(update.effective_message)
text = "{text} \n\n {bot_link}".format(text=da_msg.stylizedText,
bot_link="&#128073; <a href='https://t.me/prosmi_bot'>Предложить новость</a>")
context.bot.editMessageText(chat_id=update.effective_chat.id,
message_id=update.effective_message.message_id,
text=text, parse_mode=ParseMode.HTML)

View File

@ -0,0 +1,18 @@
from bot.DaHandler import DaHandler
from telegram import ParseMode
import bot
from bot.DaMsg import DaMsg
class TestChannelPhotoHandler(DaHandler):
def handler(self, update, context):
if bot.config['TEST_CHANNEL_ID'] == str(update.effective_chat.id):
if update.effective_message.caption is not None:
da_msg = DaMsg(update.effective_message)
text = "{text} \n\n {bot_link}".format(text=da_msg.stylizedCaption,
bot_link="&#128073; <a href='https://t.me/prosmi_bot'>Предложить новость</a>")
context.bot.editMessageCaption(chat_id=update.effective_chat.id,
message_id=update.effective_message.message_id,
caption=text, parse_mode=ParseMode.HTML)

View File

@ -0,0 +1,16 @@
from bot.DaHandler import DaHandler
from telegram import ParseMode
import bot
class TestChannelVideoHandler(DaHandler):
def handler(self, update, context):
if bot.config['TEST_CHANNEL_ID'] == str(update.effective_chat.id):
if update.effective_message.caption is not None:
text = "{text} \n\n {bot_link}".format(text=update.effective_message.caption,
bot_link="&#128073; <a href='https://t.me/prosmi_bot'>Предложить новость</a>")
context.bot.editMessageCaption(chat_id=update.effective_chat.id,
message_id=update.effective_message.message_id,
caption=text, parse_mode=ParseMode.HTML)

View File

@ -0,0 +1,13 @@
from bot.Keyboard import Keyboard
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
class AdminAnswerToBooking(Keyboard):
def get_keyboard(self):
book_id = self.get_option("book_id")
return [
[
InlineKeyboardButton("Принять", callback_data="accept={book_id}".format(book_id=book_id)),
# InlineKeyboardButton("Ответить", callback_data="answer={book_id}".format(book_id=book_id))
],
]

View File

@ -0,0 +1,25 @@
from datetime import datetime, timedelta
from bot.Keyboard import Keyboard
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
class DateToBookingKeyboard(Keyboard):
def get_keyboard(self):
current_day = datetime.now()
keyboard = []
for i in range(1, 8):
keyboard.append(
[
InlineKeyboardButton(current_day.strftime("%d.%m.%Y"),
callback_data="set_date={date}".format(date=current_day.strftime("%d.%m.%Y")))
]
)
current_day = current_day + timedelta(days=1)
keyboard.append(
[
InlineKeyboardButton("Назад", callback_data="set_date=back")
]
)
return keyboard

View File

@ -0,0 +1,18 @@
from bot.Keyboard import Keyboard
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
class FirstStepDeveloper(Keyboard):
def get_keyboard(self):
return [
[
InlineKeyboardButton("Последние проекты", callback_data='get_last_projects')
],
# [
# InlineKeyboardButton("Стать разработчиком", callback_data='set_developer')
# ],
# [
# InlineKeyboardButton("Меню заведения", callback_data='get_menu')
# ],
]

View File

@ -0,0 +1,18 @@
from bot.Keyboard import Keyboard
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
class FirstStepKeyboard(Keyboard):
def get_keyboard(self):
return [
[
InlineKeyboardButton("Авторизация", callback_data='request_code')
],
# [
# InlineKeyboardButton("Стать разработчиком", callback_data='set_developer')
# ],
# [
# InlineKeyboardButton("Меню заведения", callback_data='get_menu')
# ],
]

View File

@ -0,0 +1,18 @@
from bot.Keyboard import Keyboard
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
class FirstStepPartner(Keyboard):
def get_keyboard(self):
return [
[
InlineKeyboardButton("Запросить кандидатов", callback_data='get_developers')
],
# [
# InlineKeyboardButton("Стать разработчиком", callback_data='set_developer')
# ],
# [
# InlineKeyboardButton("Меню заведения", callback_data='get_menu')
# ],
]

View File

@ -0,0 +1,23 @@
from bot.Keyboard import Keyboard
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
class GetTableListKeyboard(Keyboard):
def get_keyboard(self):
keyboard = []
for i in range(1, 8):
keyboard.append(
[
InlineKeyboardButton("Стол {t}".format(t=i),
callback_data="set_table={t}".format(t=i))
]
)
keyboard.append(
[
InlineKeyboardButton("Назад", callback_data="set_table=back")
]
)
return keyboard

View File

@ -0,0 +1,34 @@
from bot.Keyboard import Keyboard
from telegram import InlineKeyboardButton
class VacancyNotificationToAdminKeyboard(Keyboard):
def get_keyboard(self):
keyboard = []
recipient = self.get_option("recipient")
post = self.get_option("post")
channel_link = post['channel_link'][1:]
channel_link = "https://t.me/{cl}".format(cl=channel_link)
post_link = "{channel_link}/{post_id}".format(channel_link=channel_link, post_id=post['post_id'])
recipient_role = recipient['status']
if recipient_role != 2:
keyboard.append([InlineKeyboardButton("Откликнуться",
callback_data='admin_respond_to_vacancy?ig_post_id={post_id}&dialog_id={dialog_id}'.format(
post_id=post['id'], dialog_id=recipient['dialog_id'])
)
])
if recipient_role == 2:
keyboard.append([InlineKeyboardButton("Открыть канал", url=channel_link)])
keyboard.append([InlineKeyboardButton("Открыть пост", url=post_link)])
if post['status'] != 5:
keyboard.append([InlineKeyboardButton("Запрос отправлен",
callback_data='request_sent?ig_post_id={post_id}'.format(
post_id=post['id'])
)
])
return keyboard

22
msg/AdminNotifMsg.py Normal file
View File

@ -0,0 +1,22 @@
from bot.HtmlMsg import HtmlMsg
class AdminNotifMsg(HtmlMsg):
def get_msg(self, data=None) -> str:
if data is None:
data = {}
cl = ""
recipient = ""
status = ""
if data['admin']['status'] == 2:
cl = "<b>Ссылка:</b> {channel_link}\n".format(channel_link=data['post']['channel_link'])
if 'recipient_respond' in data:
recipient = "Эксперт @{username} откликнулся на вакансию\n".format(username=data['recipient']['username'])
if 'status' in data:
status = "Статус: <b>{status}</b>\n".format(status=data['status'])
ct = "<b>Название:</b> {channel_title}\n".format(channel_title=data['post']['channel_title'])
content = "<b>Текст:</b>\n{content}".format(content=data['post']['content'])
msg = "{recipient}{status}{cl}{ct}{content}".format(cl=cl, ct=ct, content=content, recipient=recipient, status=status)
return self.get_stylized_msg(msg)

22
msg/CryptocurrencyMsg.py Normal file
View File

@ -0,0 +1,22 @@
from bot.DaMsg import DaMsg
from pycoingecko import CoinGeckoAPI
from bot import config
class CryptocurrencyMsg(DaMsg):
@staticmethod
def get_msg(data=None) -> str:
if data is None:
data = {}
cg = CoinGeckoAPI()
codes = config['CRYPTO_CHARCODES'].split(" ")
res = cg.get_price(ids=codes, vs_currencies=['usd'])
msg = '&#128200; Курс криптовалют на сегодня:\n\n'
for currency in codes:
msg = msg + "<b>" + currency + "</b>: " + str(res[currency]['usd']) + "$\n\n"
msg = msg + "&#128073; <a href='https://t.me/prosmi_bot'>Предложить новость</a>"
return msg

35
msg/ExchangeMsg.py Normal file
View File

@ -0,0 +1,35 @@
from bot.DaMsg import DaMsg
from exchange.Cbr import Cbr
class ExchangeMsg(DaMsg):
@staticmethod
def get_msg(data=None) -> str:
if data is None:
data = {}
cbr = Cbr()
currencies = cbr.get_by_codes()
msg = '&#128200; Курс валют ЦБ РФ на сегодня:\n\n'
for currency in currencies:
circle = ExchangeMsg.get_circle(currency['Value'], currency['Previous'])
arrow = ExchangeMsg.get_arrow(currency['Value'], currency['Previous'])
msg = msg + "{n}: {c} <b>{v}</b> {a}\n\n".format(n=currency['Name'], c=circle, v=currency['Value'], a=arrow)
msg = msg + "&#128073; <a href='https://t.me/prosmi_bot'>Предложить новость</a>"
return msg
@staticmethod
def get_arrow(value, previous) -> str:
if value > previous:
return "&#11014;"
return "&#11015;"
@staticmethod
def get_circle(value, previous) -> str:
if value > previous:
return "&#128994;"
return "&#128308;"

7
msg/SetEmailMsg.py Normal file
View File

@ -0,0 +1,7 @@
from bot.DaMsg import DaMsg
class SetEmailMsg(DaMsg):
def get_msg(data=None) -> str:
return "Укажите пожалуйста email, который вы используете на ITGuild, если у вас нет учетной записи, то мы ее создадим."

9
msg/UserMsg.py Normal file
View File

@ -0,0 +1,9 @@
from bot.DaMsg import DaMsg
class HelloMsg(DaMsg):
def get_msg(data=None) -> str:
return ("Здравствуйте. Для более удобной работы с нашим ботом, вам необходимо авторизироваться. "
"Перейдите по сслыки <a href='https://itguild.info/profile/settings'>https://itguild.info/profile/settings</a>, "
"в блоке «Телеграмм бот» нажмите на кнопку «Сгенерировать», полученный код отправте в телеграмм бот.")

13
msg/UserPostMsg.py Normal file
View File

@ -0,0 +1,13 @@
from bot.HtmlMsg import HtmlMsg
class UserPostMsg(HtmlMsg):
def get_msg(self, data=None) -> str:
if data is None:
data = {}
content = "{content}".format(content=data['post']['content'])
msg = "{content}".format(content=content)
msg = self.replace_tag_with_content(msg, "secure")
return self.get_stylized_msg(msg)