# Path: golem/core/message_parser.py
# def parse_text_message(text, num_tries=1):
#     if len(ENTITY_EXTRACTORS) <= 0:
#         logging.warning('No entity extractors configured!')
#         return {'type': 'message', 'entities': {'_message_text': [{'value': text}]}}
# 
#     entities = {}
# 
#     for extractor in ENTITY_EXTRACTORS:
#         append = extractor.extract_entities(text)
#         for entity, values in append.items():
#             entities.setdefault(entity, []).extend(values)
# 
#     logging.debug('Extracted entities:', entities)
#     append = parse_additional_entities(text)
# 
#     for (entity, value) in re.findall(re.compile(r'/([^/]+)/([^/]+)/'), text):
#         if not entity in append:
#             append[entity] = []
#         append[entity].append({'value': value})
# 
#     # add all new entity values
#     for entity, values in append.items():
#         if not entity in entities:
#             entities[entity] = []
#         entities[entity] += values
# 
#     entities['_message_text'] = [{'value': text}]
# 
#     parsed = {'entities': entities, 'type': 'message'}
# 
#     return parsed
# 
# Path: golem/core/persistence.py
# def get_redis():
#     global _connection_pool
#     global _redis
#     if not _connection_pool:
#         config = settings.GOLEM_CONFIG.get('REDIS')
#         _connection_pool = redis.ConnectionPool(
#             host=config['HOST'],
#             port=config['PORT'],
#             password=config['PASSWORD'],
#             db=0,
#             max_connections=2
#         )
#     if not _redis:
#         _redis = redis.StrictRedis(connection_pool=_connection_pool)
#     return _redis
# 
# Path: golem/tasks.py
# @shared_task
# def accept_user_message(session: dict, raw_message):
#     from golem.core.dialog_manager import DialogManager
#     session = ChatSession.from_json(session)
#     print("Accepting message - chat id {}, message: {}".format(session.chat_id, raw_message))
# 
#     dialog = DialogManager(session)
#     parsed = session.interface.parse_message(raw_message)
#     _process_message(dialog, parsed)
# 
#     should_log_messages = settings.GOLEM_CONFIG.get('SHOULD_LOG_MESSAGES', False)
# 
#     if should_log_messages and 'text' in raw_message:
#         text = raw_message['text']
#         message_logger.on_message.delay(session, text, dialog, from_user=True)
#     return True  # FIXME


import json
import logging
import string
import random
import requests
from datetime import datetime, timedelta
from typing import Optional
from django.conf import settings
from golem.core.message_parser import parse_text_message
from golem.core.persistence import get_redis
from golem.tasks import accept_user_message
        from django.urls import reverse
        from golem.core.interfaces.adapter.telegram import TelegramAdapter
    def parse_message(raw, num_tries=1):
        if 'message' in raw and 'text' in raw['message']:
            return parse_text_message(raw['message']['text'])
        elif 'callback_query' in raw:
            callback_query = raw['callback_query']
            data = TelegramInterface.retrieve_callback(callback_query.get('data'))
            if data:
                payload = json.loads(data)
                payload['_message_text'] = [{'value': None}]
                return {'entities': payload, 'type': 'postback'}
        return {'type': 'undefined'}

    @staticmethod
    def persist_callback(payload) -> str:
        """
        Persists payload to be used with Telegram callbacks (which can be max. 64B)
        and returns a string that can be used to retrieve the payload from redis.
        The payload will be persisted for a week.
        :param  payload     Payload to be persisted in Redis.
        :return             Unique string associated with the payload, which can be sent to Telegram.
        """
        redis = get_redis()
        key = ''.join(random.choice(string.hexdigits) for i in range(63))
        while redis.exists(key):
            key = ''.join(random.choice(string.hexdigits) for i in range(63))
        redis.set(key, payload, ex=3600 * 24 * 7)
        return key

    @staticmethod
    def retrieve_callback(key) -> Optional[str]:

# Path: golem/core/message_parser.py
# def parse_text_message(text, num_tries=1):
#     if len(ENTITY_EXTRACTORS) <= 0:
#         logging.warning('No entity extractors configured!')
#         return {'type': 'message', 'entities': {'_message_text': [{'value': text}]}}
# 
#     entities = {}
# 
#     for extractor in ENTITY_EXTRACTORS:
#         append = extractor.extract_entities(text)
#         for entity, values in append.items():
#             entities.setdefault(entity, []).extend(values)
# 
#     logging.debug('Extracted entities:', entities)
#     append = parse_additional_entities(text)
# 
#     for (entity, value) in re.findall(re.compile(r'/([^/]+)/([^/]+)/'), text):
#         if not entity in append:
#             append[entity] = []
#         append[entity].append({'value': value})
# 
#     # add all new entity values
#     for entity, values in append.items():
#         if not entity in entities:
#             entities[entity] = []
#         entities[entity] += values
# 
#     entities['_message_text'] = [{'value': text}]
# 
#     parsed = {'entities': entities, 'type': 'message'}
# 
#     return parsed
# 
# Path: golem/core/persistence.py
# def get_redis():
#     global _connection_pool
#     global _redis
#     if not _connection_pool:
#         config = settings.GOLEM_CONFIG.get('REDIS')
#         _connection_pool = redis.ConnectionPool(
#             host=config['HOST'],
#             port=config['PORT'],
#             password=config['PASSWORD'],
#             db=0,
#             max_connections=2
#         )
#     if not _redis:
#         _redis = redis.StrictRedis(connection_pool=_connection_pool)
#     return _redis
# 
# Path: golem/tasks.py
# @shared_task
# def accept_user_message(session: dict, raw_message):
#     from golem.core.dialog_manager import DialogManager
#     session = ChatSession.from_json(session)
#     print("Accepting message - chat id {}, message: {}".format(session.chat_id, raw_message))
# 
#     dialog = DialogManager(session)
#     parsed = session.interface.parse_message(raw_message)
#     _process_message(dialog, parsed)
# 
#     should_log_messages = settings.GOLEM_CONFIG.get('SHOULD_LOG_MESSAGES', False)
# 
#     if should_log_messages and 'text' in raw_message:
#         text = raw_message['text']
#         message_logger.on_message.delay(session, text, dialog, from_user=True)
#     return True  # FIXME


# Path: golem/core/interfaces/telegram.py
import json
import logging
import string
import random
import requests
from datetime import datetime, timedelta
from typing import Optional
from django.conf import settings
from golem.core.message_parser import parse_text_message
from golem.core.persistence import get_redis
from golem.tasks import accept_user_message
        from django.urls import reverse
        from golem.core.interfaces.adapter.telegram import TelegramAdapter

    def parse_message(raw, num_tries=1):
        if 'message' in raw and 'text' in raw['message']:
            return parse_text_message(raw['message']['text'])
        elif 'callback_query' in raw:
            callback_query = raw['callback_query']
            data = TelegramInterface.retrieve_callback(callback_query.get('data'))
            if data:
                payload = json.loads(data)
                payload['_message_text'] = [{'value': None}]
                return {'entities': payload, 'type': 'postback'}
        return {'type': 'undefined'}

    @staticmethod
    def persist_callback(payload) -> str:
        """
        Persists payload to be used with Telegram callbacks (which can be max. 64B)
        and returns a string that can be used to retrieve the payload from redis.
        The payload will be persisted for a week.
        :param  payload     Payload to be persisted in Redis.
        :return             Unique string associated with the payload, which can be sent to Telegram.
        """
        redis = get_redis()
        key = ''.join(random.choice(string.hexdigits) for i in range(63))
        while redis.exists(key):
            key = ''.join(random.choice(string.hexdigits) for i in range(63))
        redis.set(key, payload, ex=3600 * 24 * 7)
        return key

    @staticmethod
    def retrieve_callback(key) -> Optional[str]:

        redis = get_redis()