|
@@ -0,0 +1,245 @@
|
|
|
+import hashlib
|
|
|
+from datetime import datetime
|
|
|
+import config
|
|
|
+import logging
|
|
|
+
|
|
|
+from webservice_running.handlers.core.JabberBot import JabberBot
|
|
|
+from webservice_running.handlers.core.lib import run_process
|
|
|
+from webservice_running.handlers.core.SystemdKiller import SystemdKiller
|
|
|
+from webservice_running.handlers.core.requesters import TicketRequester
|
|
|
+
|
|
|
+from slixmpp.stanza import Message
|
|
|
+from time import sleep
|
|
|
+from classes.Ticket import Ticket
|
|
|
+from typing import List
|
|
|
+from concurrent.futures import ThreadPoolExecutor
|
|
|
+from config import KEYS
|
|
|
+
|
|
|
+botname = "platform_access_request_pending"
|
|
|
+operating_status = 320
|
|
|
+
|
|
|
+JID = botname + "@" + config.JSERVER
|
|
|
+PORT = config.PORT
|
|
|
+PASSWORD = hashlib.md5((botname + config.PASSWORD).encode('utf-8')).hexdigest()
|
|
|
+
|
|
|
+bot = JabberBot(JID, PASSWORD)
|
|
|
+
|
|
|
+listen_to = [
|
|
|
+ "test@ej.sharix-app.org",
|
|
|
+ "platform_template_bot@ej.sharix-app.org"
|
|
|
+]
|
|
|
+""" Список jid, от которых можно получать сообщения этому боту """
|
|
|
+
|
|
|
+proceed_to = [
|
|
|
+ JID,
|
|
|
+ "platform_st_request_declined@ej.sharix-app.org",
|
|
|
+ "platform_service_request_forcemajeure@ej.sharix-app.org"
|
|
|
+]
|
|
|
+""" Список jid, кому бот может отправлять сообщения в результате обработки заявки """
|
|
|
+
|
|
|
+ASSIGNET_TO_ATTEMPTS = 3
|
|
|
+""" Количество пользователей, которым будет отправлено сообщение """
|
|
|
+INTERVAL_ATTEMPTS = 3
|
|
|
+""" Количество сообщений, которые будут отправлены пользователю """
|
|
|
+# INTERVAL_TIME = 30 * 60 # 30 минут в секундах
|
|
|
+INTERVAL_TIME = 5 # Для проверки
|
|
|
+""" Интервал времени между попытками отправки сообщения """
|
|
|
+
|
|
|
+TEMP_TICKETS: List[Ticket] = []
|
|
|
+""" Список тикетов для добавления в очередь обработки """
|
|
|
+ID_TICKETS_FOR_REMOVE: List[int] = []
|
|
|
+""" Список id тикетов для удаления """
|
|
|
+
|
|
|
+ticket_requester = TicketRequester(KEYS.PLATFORM_ACCESS_REQUEST_PENDING)
|
|
|
+
|
|
|
+def message_handler(msg: Message):
|
|
|
+ """Обработчик входящих сообщений"""
|
|
|
+
|
|
|
+ if msg['type'] in ('chat', 'normal'):
|
|
|
+ text = msg['body'] # текст сообщения боту
|
|
|
+ sender = msg['from'] # отправитель сообщения
|
|
|
+
|
|
|
+ sender_name = str(sender).split("/")[0]
|
|
|
+ if sender_name in listen_to:
|
|
|
+ if text is not None:
|
|
|
+ logging.info(f"Сообщение получено")
|
|
|
+
|
|
|
+ # match ACTION:
|
|
|
+ # case "add_ticket":
|
|
|
+ # match sender_name:
|
|
|
+ # case "platform_*_request_*":
|
|
|
+ # TEMP_TICKETS.append(ticket)
|
|
|
+ # case "remove_ticket":
|
|
|
+ # ID_TICKETS_FOR_REMOVE.append(id)
|
|
|
+
|
|
|
+
|
|
|
+def start_handler():
|
|
|
+ """Событие запуска обработчика."""
|
|
|
+
|
|
|
+ logging.info(">>>>> %s |---| %s <<<<<", JID, PASSWORD)
|
|
|
+
|
|
|
+ tickets: List[Ticket] = ticket_requester.all({"status": 320})
|
|
|
+
|
|
|
+ with ThreadPoolExecutor() as executor:
|
|
|
+ killer = SystemdKiller()
|
|
|
+
|
|
|
+ while not killer.exit_event.is_set():
|
|
|
+ # Получение тикетов от других обработчиков
|
|
|
+ tickets += TEMP_TICKETS
|
|
|
+ TEMP_TICKETS.clear()
|
|
|
+
|
|
|
+ # Фильтрация тикетов от лишних id
|
|
|
+ tickets = [ticket for ticket in tickets if ticket.id not in ID_TICKETS_FOR_REMOVE]
|
|
|
+ ID_TICKETS_FOR_REMOVE.clear()
|
|
|
+
|
|
|
+ # Параллельная обработка всех тикетов
|
|
|
+ processed = list(executor.map(run_process(interval_attempts_unlimited, processing), tickets))
|
|
|
+
|
|
|
+ # Фильтрация тикетов
|
|
|
+ tickets = [t for t in processed if t is not None]
|
|
|
+
|
|
|
+ logging.debug('Кол-во тикетов:' + str(len(tickets)))
|
|
|
+ logging.debug("Sleep")
|
|
|
+ killer.exit_event.wait(timeout=INTERVAL_TIME)
|
|
|
+
|
|
|
+
|
|
|
+# START CUSTOM FUNCTIONS
|
|
|
+
|
|
|
+def interval_attempts_unlimited(ticket: Ticket) -> None:
|
|
|
+ logging.debug(f"Лимит попыток обработки тикета {ticket.id} исчерпан")
|
|
|
+
|
|
|
+
|
|
|
+ response = ticket_requester.patch(ticket, {"status": 359})
|
|
|
+
|
|
|
+ # TODO: implement send ticket changed to next handler
|
|
|
+ # bot.send_message(JID, f"Сообщение отправлено {JID}: {datetime.now()}")
|
|
|
+ # bot message:
|
|
|
+ # {
|
|
|
+ # "action": "add_ticket"
|
|
|
+ # "ticket_id": 0
|
|
|
+ # "ticket_list_id": 0
|
|
|
+ # }
|
|
|
+
|
|
|
+
|
|
|
+def processing(ticket: Ticket) -> None:
|
|
|
+ logging.debug(f"Начало обработки тикета {ticket.id}. Лимит: {ticket.interval_attempts}")
|
|
|
+
|
|
|
+ message = f"Тикет {ticket.id} ожидает решения"
|
|
|
+
|
|
|
+ # send_notification_to_admins(ticket, message)
|
|
|
+ # bot.send_message(ticket.assigned_to, message)
|
|
|
+
|
|
|
+ logging.debug(f"Конец обработки тикета {ticket.id}")
|
|
|
+
|
|
|
+
|
|
|
+def send_notification_to_admins(ticket: Ticket, admins: List[str], message: str) -> None:
|
|
|
+ """Отправка уведомления администратору о новом тикете."""
|
|
|
+ for admin in admins:
|
|
|
+ bot.send_message(admin, message)
|
|
|
+ logging.info(f"Уведомление отправлено администраторам: {ticket.id}")
|
|
|
+
|
|
|
+
|
|
|
+def set_assigned_to(ticket: Ticket) -> Ticket:
|
|
|
+ """Проверка, назначен ли тикет на пользователя"""
|
|
|
+ if ticket.assigned_to is None:
|
|
|
+ # TODO: add function how select user from db
|
|
|
+ # ticket.assigned_to = "username"
|
|
|
+
|
|
|
+ # assigned_to = ticket_requester.patch(ticket, {"assigned_to": "platform_access_request_pending@ej.sharix-app.org"})
|
|
|
+ # ticket.assigned_to = assigned_to
|
|
|
+ None
|
|
|
+ return ticket
|
|
|
+
|
|
|
+
|
|
|
+# def get_token():
|
|
|
+# return jsreq.requestGetToken(botname, PASSWORD, config.API_URL + "/auth/token/login/")
|
|
|
+
|
|
|
+# def set_tasklist(token):
|
|
|
+# global tasklist
|
|
|
+
|
|
|
+# tasklist = []
|
|
|
+# tasklist = jsreq.requestGetList(token, config.API_URL + "/tickets/api/tickets/?list_id=10")
|
|
|
+
|
|
|
+
|
|
|
+# END CUSTOM FUNCTIONS
|
|
|
+
|
|
|
+
|
|
|
+# ---------------------------------------
|
|
|
+# ---------------------------------------
|
|
|
+# ---------------------------------------
|
|
|
+# ---------------------------------------
|
|
|
+# ---------------------------------------
|
|
|
+
|
|
|
+
|
|
|
+# # обработчик входящих сообщений
|
|
|
+# def message_handler(conn, mess):
|
|
|
+# text = mess.getBody() # текст сообщения боту
|
|
|
+# user = mess.getFrom() # отправитель сообщения
|
|
|
+
|
|
|
+# print(str(user).split("/")[0])
|
|
|
+# if (str(user).split("/")[0]) in listen_to:
|
|
|
+# print(text)
|
|
|
+# print(mess)
|
|
|
+
|
|
|
+# if text is not None:
|
|
|
+# orderObj = jsreq.jsonToOrderTicket(text)
|
|
|
+# print(orderObj)
|
|
|
+# tasklist.append(orderObj)
|
|
|
+# bot.bot_log(str(datetime.now()) + " Поступивший заказ успешно добавлен в очередь обработки\n")
|
|
|
+
|
|
|
+
|
|
|
+# def platform_access_request_pending_wait(period, localtask):
|
|
|
+# bot.bot_log(botname + " " + str(datetime.now()) + " " + "Заказ ожидает\n")
|
|
|
+# time.sleep(period)
|
|
|
+
|
|
|
+# # ВАЖНО! Надо скорее всего через API редактировать заказ, иначе возможна потеря данных
|
|
|
+# localtask.title = localtask.title + "1"
|
|
|
+
|
|
|
+# # обязательно данный обработчик должен заканчиваться передачей заказа куда-то на обработку дальше - обратно или другому, иначе оно потеряется
|
|
|
+# bot.proceed_status(proceed_to[1], localtask)
|
|
|
+# bot.bot_log(botname + " " + str(datetime.now()) + " " + "Заказ перенаправлен\n")
|
|
|
+
|
|
|
+
|
|
|
+# def platform_access_request_pending_process(localtask):
|
|
|
+# bot.bot_log(botname + " " + str(datetime.now()) + " " + "Заказ в обработчике\n")
|
|
|
+
|
|
|
+# push_notifications(localtask)
|
|
|
+# platform_access_request_pending_wait(100, localtask)
|
|
|
+
|
|
|
+
|
|
|
+# # Пока не уверен
|
|
|
+# def push_notifications(localtask):
|
|
|
+# # Отправка уведомлений
|
|
|
+# # ...
|
|
|
+# return True
|
|
|
+
|
|
|
+
|
|
|
+# def platform_access_request_pending():
|
|
|
+# while (len(tasklist)):
|
|
|
+# localtask = tasklist.pop(0)
|
|
|
+# bot.bot_log(botname + " " + datetime.now().strftime('%Y-%m-%d') + " " + "Заказ в очереди на обработке\n")
|
|
|
+# print("EACH TASKLIST", tasklist)
|
|
|
+
|
|
|
+# if (localtask.status != operating_status):
|
|
|
+# bot.proceed_status(proceed_to[-1], localtask)
|
|
|
+# bot.bot_log(botname + " " + str(datetime.now()) + " " + "Заказ не по адресу, перенаправляем на форсмажор\n")
|
|
|
+# continue
|
|
|
+
|
|
|
+# # if (localtask.title!="10"):
|
|
|
+# # t1=threading.Thread(target=platform_service_request_booked_wait, args=(5,localtask))
|
|
|
+# # t1.start()
|
|
|
+
|
|
|
+# # if (localtask.title=="101"):
|
|
|
+# # t1=threading.Thread(target=platform_service_request_booked_process, args=(10,localtask))
|
|
|
+# # t1.start()
|
|
|
+
|
|
|
+# t1 = threading.Thread(target=platform_access_request_pending_process, args=(localtask))
|
|
|
+# t1.start()
|
|
|
+
|
|
|
+# # если никакие обработчики не подошли - отправляем обратно в очередь
|
|
|
+# bot.proceed_status(proceed_to[0], localtask)
|
|
|
+# print("Заказ возвращен в очередь\n")
|
|
|
+# print(tasklist)
|
|
|
+
|
|
|
+
|
|
|
+# # пустой список заказов
|