#!/usr/bin/env python
# -*- coding: utf-8 -*-
import glob
import logging
import os.path
import urllib3
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
from telegram import ParseMode
from telegram.ext.callbackcontext import CallbackContext
from telegram.ext.callbackqueryhandler import CallbackQueryHandler
from telegram.ext.commandhandler import CommandHandler
from telegram.ext.conversationhandler import ConversationHandler
from telegram.ext.filters import Filters
from telegram.ext.messagehandler import MessageHandler
from telegram.ext.updater import Updater
from telegram.update import Update
import database_lib as DB
import libreremo_assets as txt
from libreremo_conf import TOKEN, CALIBRE_DIR, MIN_QUERY_LENGTH
logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO
)
db = DB.Database(CALIBRE_DIR + "metadata.db")
def start(update: Update, context: CallbackContext):
update.message.reply_text(txt.INTRO, parse_mode=ParseMode.HTML)
def show_help(update: Update, context: CallbackContext):
update.message.reply_text(txt.HELP, parse_mode=ParseMode.HTML)
def _ask_resource_type(update, context):
keyboard = [[InlineKeyboardButton(text="Titolo", callback_data="titolo")],
[InlineKeyboardButton(text="Autore", callback_data="autore")],
[InlineKeyboardButton(text="\u274C Annulla \u274C", callback_data="stop")]]
reply_markup = InlineKeyboardMarkup(keyboard)
update.message.reply_text(
text="In base a cosa vuoi cercare il tuo libro?",
reply_markup=reply_markup)
return GET_RESOURCE_TYPE
def _get_resource_type(update, context):
query = update.callback_query
query.answer()
if query.data == "stop":
query.edit_message_text("Ricerca annullata", None)
return ConversationHandler.END
context.user_data["resource"] = query.data
query.edit_message_text(
text="quale {} stai cercando?".format(query.data),
parse_mode=ParseMode.HTML
)
return GET_RESOURCE
def _get_resource(update, context):
resource = update.message.text
result_list = []
if len(resource) <= MIN_QUERY_LENGTH:
update.message.reply_text(txt.SHORTQUERY)
update.message.reply_text("Cosa stai cercando?")
return GET_RESOURCE
if context.user_data["resource"] == "titolo":
result_list = db.select_books_by_title(resource)
text = "Scegli uno di questi libri"
handler = GET_BOOK
elif context.user_data["resource"] == "autore":
result_list = db.select_authors(resource)
text = "Scegli uno di questi autori"
handler = GET_AUTHOR
logging.info("asked resource {res}: {txt}"
.format(res=context.user_data["resource"], txt=resource))
if not result_list:
logging.info("cannot found result for {}".format(resource))
update.message.reply_text(txt.FILENOTFOUND, parse_mode=ParseMode.HTML)
return ConversationHandler.END
reply_markup = __format_reply_markup(result_list)
update.message.reply_text(
text=text,
reply_markup=reply_markup)
return handler
def _get_author(update: Update, context: CallbackContext):
query = update.callback_query
query.answer()
if query.data == "stop":
query.edit_message_text("Ricerca annullata", None)
return ConversationHandler.END
book_list = db.select_books_by_author(query.data)
if not book_list:
logging.info(f"cannot find books for author: {query.data}")
query.edit_message_text(
text="Mi dispiace ma non riesco a trovare libri per questo autore")
return ConversationHandler.END
query.edit_message_text(
text="Questi sono i libri che abbiamo per {}".format(
"".join(query.data.split(",")[::-1])),
reply_markup=__format_reply_markup(book_list),
parse_mode=ParseMode.HTML
)
return GET_BOOK
def _get_book(update: Update, context: CallbackContext):
query = update.callback_query
query.answer()
if query.data == "stop":
query.edit_message_text("Ricerca annulata", None)
return ConversationHandler.END
chat_id = query.message.chat_id
query.edit_message_reply_markup()
query.message.reply_text(
"Hai scelto: {}".format("(".join(
query.data.split("/", 1)[1]
.split("(")[:-1])),
parse_mode=ParseMode.HTML
)
query.message.reply_text(
'Stiamo caricando il file, sii paziente se il tuo libro non arriva subito')
filepath = CALIBRE_DIR + query.data
if os.path.isdir(filepath + "/splitted"):
filepath = filepath + "/splitted"
try:
for file in glob.glob(filepath + "/*.pdf"):
with open(file, 'rb') as doc:
context.bot.send_document(chat_id, doc, timeout=120)
logging.info("Sharing {}".format(file))
except urllib3.exceptions.HTTPError as e: # cannot handle exception
logging.error(e)
query.message.reply_text(
"Abbiamo qualche problema di connessione, ritenta più tardi")
except Exception as e:
logging.info("cannot send {}".format(filepath))
logging.error(e)
query.message.reply_text(
"Non riesco a mandarti il file, riprova più tardi")
return ConversationHandler.END
def _cnv_stop(update: Update, context: CallbackContext):
# context.bot.edit_message_reply_markup()
return ConversationHandler.END
def search_by_title(update: Update, context: CallbackContext):
update.message.reply_text("che libro stai cercando?")
context.user_data["resource"] = "titolo"
return GET_RESOURCE
def search_by_title_default(update: Update, context: CallbackContext):
context.user_data["resource"] = "titolo"
return _get_resource(update, context)
def search_by_author(update: Update, context: CallbackContext):
update.message.reply_text("di quale autore stai cercando i libri?")
context.user_data["resource"] = "autore"
return GET_RESOURCE
def unknown(update: Update, context: CallbackContext):
update.message.reply_text(
"{} non è un comando valido, prova con /help".format(update.message.text))
def __format_reply_markup(list_of_res):
inline_keyboard = [[InlineKeyboardButton(
text=res.format_text(), callback_data=res.format_data())]
for res in list_of_res]
inline_keyboard.append([InlineKeyboardButton(
text="\u274C Annulla \u274C", callback_data="stop")])
return InlineKeyboardMarkup(inline_keyboard)
def handle_error(update: Update, context: CallbackContext):
context.bot.send_message(
chat_id=update.callback_query.message.chat_id,
text="Oh no, qualcosa è andato storto, riprova più tardi...")
logging.error(context.error)
return ConversationHandler.END
GET_RESOURCE_TYPE, ASK_RESOURCE, GET_RESOURCE, GET_BOOK, GET_AUTHOR = range(5)
cnv_handler = ConversationHandler(
entry_points=[CommandHandler('search', _ask_resource_type),
CommandHandler('search_by_title', search_by_title),
CommandHandler('search_by_author', search_by_author),
MessageHandler(Filters.text, search_by_title_default)],
states={
GET_RESOURCE_TYPE: [CallbackQueryHandler(_get_resource_type), MessageHandler(Filters.text, _cnv_stop)],
GET_RESOURCE: [MessageHandler(Filters.text, _get_resource)],
GET_AUTHOR: [CallbackQueryHandler(_get_author)],
GET_BOOK: [CallbackQueryHandler(_get_book)],
},
fallbacks=[CommandHandler('stop', _cnv_stop),
MessageHandler(Filters.command, _cnv_stop)],
)
def main():
updater = Updater(TOKEN, use_context=True, arbitrary_callback_data=True)
updater.dispatcher.add_handler(CommandHandler('start', start))
updater.dispatcher.add_handler(CommandHandler('help', show_help))
updater.dispatcher.add_handler(cnv_handler)
updater.dispatcher.add_handler(MessageHandler(Filters.command, unknown)) # Filters out unknown commands
updater.dispatcher.add_error_handler(handle_error)
updater.start_polling()
updater.idle()
if __name__ == '__main__':
main()