import requests                                          #подключаем внешнюю библиотеку для работы с запросами
import json                                              #стандартная библиотека для записи в json-файл
import re                                                #стандартная библиотека для работы с регулярными выражениями
from flask import Flask                                  #импортируем из библиотеки flask класс flask для создания его экземпляра
from flask import request                                #для работы вьюхи с запросами сервера телеграм
from flask import jsonify                                #для возвращения вьюхой json-объекта
from flask_sslify import SSLify                          #для создания требуемого телеграмом защищенного соединения с нашим сервером

app = Flask(__name__)                                    #создаем экземпляр класса Flask с сылкой на имя текущего файла в качестве аргумента
sslify = SSLify(app)                                     #создаем экземпляр класса SSLify

token = '704310053:AAETVX6byAP8WmIbhRoIzx1U-MX3VzmQ5aA'  #уникальный атрибут бота для работы с запросами
URL = 'https://api.telegram.org/bot' + token + '/'       #постоянная часть url для запросов

#Вспомогательная функция, записывающая ответ сервера телеграм в файлик
def write_json(data,filename='answer.json'):             #принимает данные и имя файла, куда будет писаться ответ в виде json-объекта
    with open(filename, 'w') as f:                       #контекстным менеджером открываем файл для записи и сохраняем как файловый объект f
        json.dump(data, f, indent=2, ensure_ascii=False) #записываем получаемые данные в f, делаем индентацию в 2 пробела, учитываем кириллицу и спец.символы

#Метод отправки телеграмом сообщений пользователю
def send_message(chat_id, text):                         #передаем методу id чата и текст сообщения
    answer = {'chat_id': chat_id, 'text': text}          #формируем словарь из принятых параметров
    r = requests.post(URL + 'sendMessage', json=answer)  #делаем post-запрос по url с методом sendMessage, передавая телеграму созданный словарик
    write_json(r.json())                                 #преобразуем полученный от телеграма ответ r в словарь и записываем в файл
    return r.json()                                      #возвращаем полученный json-объект

#Метод парсинга сообщения пользователя
def parse_text(text):                                    #передаем текст сообщения
    pattern = r'/\w+'                                    #создаем шаблон, без экранирования спец.знаков забирающий текст с 1м символом '/' и последующие буквы, цифры и '_' до пробела или соответствующего знака
    crypto = re.search(pattern, text).group()            #ищем в тексте набор символов, соответствующий шаблону, и методом group преобразуем результат в то, что можно увидеть
    return crypto[1:]                                    #возвращаем результат со 2го символа, без 1го '/'

#Метод получения цены крипты в долларах с coinmarketcap.com
def get_price(crypto):                                                #передаем название интересующей крипты
    url = 'https://api.coinmarketcap.com/v1/ticker/{}'.format(crypto) #формируем url для запроса к сайту, подставляя название валюты
    r = requests.get(url).json()                                      #делаем get-запрос по нему, полученный ответ преобразуем в json-объект и записываем в r
    price = r[-1]['price_usd']                                        #в списке r обращаемся к ключу price_usd последнего элемента
    return price                                                      #возвращаем полученную цену

#Реализация вьюхи проекта
@app.route('/', methods=['POST', 'GET'])                 #для декоратора app указываем корневой путь для обращения пользователя и индекс принимаемых запросов
def index():                                             #функция-обработчик, вызываемая при обращении к корневому пути
    if request.method == 'POST':                         #если метод запроса от сервера телеграма - post
        r = request.get_json()                           #принимаем посылаемый json-объект с обновлениями и записываем в r
        chat_id = r['message']['chat']['id']             #распарсиваем полученный словарь до значения chat_id
        message = r['message']['text']                   #получаем текст сообщения
        pattern = r'/\w+'                                #указываем шаблон для поиска команд
        if re.search(pattern, message):                  #если в тексте сообщения пользователя найдена команда
            price = get_price(parse_text(message))       #вычленяем из текста название крипты и по нему получаем ее цену с coinmarketcap.com
            send_message(chat_id, text=price)            #отправляем пользователю ответ с id чата и ценой крипты
        return jsonify(r)                                #возвращаем json-объект, как того требует вьюха
    return '<h1>Bot welcomes you.<h1>'                   #иначе это уведомляющая строка

#Точка входа
if __name__ == '__main__':                               #используется для избежания ошибки запуска app и файлом, и нашим сервером
    app.run()                                            #запускаем flask-объект

