diff --git a/database_lib.py b/database_lib.py index 5774de2..080a856 100644 --- a/database_lib.py +++ b/database_lib.py @@ -6,7 +6,8 @@ import sqlite3 as sql3 logger = logging.getLogger(__name__) -class Database(): + +class Database: def __init__(self, filename): self.filename = filename @@ -17,7 +18,7 @@ class Database(): result_list = None try: self.con = sql3.connect(self.filename) - self.con.row_factory = factory + self.con.row_factory = factory self.cur = self.con.cursor() logging.info("Connection to db open") self.cur.execute(sql) @@ -26,8 +27,8 @@ class Database(): logging.info("an error occured", error) finally: if self.con: - self.con.close() - logging.info("Connection to db closed") + self.con.close() + logging.info("Connection to db closed") return result_list def select_books_by_title(self, query): @@ -36,17 +37,17 @@ class Database(): SELECT title, author_sort, path FROM books WHERE title LIKE '{query}'; """ - return self._execute(sql, res.book_factory) - + return self._execute(sql, res.book_factory) + def select_books_by_author(self, query): query = self.__format_query(query) sql = f""" SELECT title, author_sort, path FROM books WHERE books.author_sort LIKE '%' || (SELECT sort FROM authors - WHERE sort = '{query}') || '%'; + WHERE sort LIKE '%{query}%') || '%'; """ - return self._execute(sql, res.book_factory) + return self._execute(sql, res.book_factory) def select_authors(self, query): query = self.__format_query(query) diff --git a/libreremo_assets.py b/libreremo_assets.py new file mode 100644 index 0000000..3d16282 --- /dev/null +++ b/libreremo_assets.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +INTRO = """ +Ciao, questo è il nuovo bot telegram di Libreremo, un progetto politico che da anni il collettivo universitario fiorentino porta avanti distribuendo ogni anno centinaia di testi universitari GRATUITAMENTE per contrastare la mercificazione della cultura e il carolibri. + +Il carolibri è da sempre, e soprattutto negli ultimi anni, un peso non indifferente per le tasche degli studenti e delle loro famiglie. Ma la nostra critica non è solo economica, pur costituendo già questa una difficoltà per tanti studenti costretti ad abbandonare gli studi. È anche politica, verso una concezione della cultura che vede quest’ultima come un bene acquistabile da chi può pagarselo, invece che un mezzo a disposizione di tutti e tutte per la propria crescita e quella della società nel suo complesso. +Una concezione questa che, purtroppo, permea l’intero mondo dell’istruzione e si fa particolarmente pesante in università. + +Qua i nostri riferimenti social, stay tuned... +Facebook +Instagram +Mail ColPol +Mail Krisis + +Per cominciare a cercare scrivi il titolo del libro oppure usa il menu comandi a fianco della chat o scrivi uno dei seguenti comandi: + +/search Per la ricerca generica +/search_by_title Per la ricerca per titolo +/search_by_author Per la ricerca per autore +/help Se hai bisogno di aiuto +""" + +HELP = """ +Ciao, questo è il nuovo bot telegram di Libreremo, un progetto politico che da anni il collettivo universitario fiorentino porta avanti distribuendo ogni anno centinaia di testi universitari GRATUITAMENTE per contrastare la mercificazione della cultura e il carolibri. +Per cominciare a cercare scrivi il titolo del libro oppure usa il menu comandi a fianco della chat o scrivi uno dei seguenti comandi: + +/help Visualizza questo aiuto +/search Per la ricerca generica +/search_by_title Per la ricerca per titolo +/search_by_author Per la ricerca per autore +""" + +FILENOTFOUND = "Mi dispiace non ho trovato niente, prova a fare una ricerca più generica o a cercare per autore" + +SHORTQUERY = "Scusa non ho capito cosa vuoi cercare, prova ad inserire quello che stai cercando per esteso" \ No newline at end of file diff --git a/libreremo_bot.py b/libreremo_bot.py index 2728877..13b53e4 100644 --- a/libreremo_bot.py +++ b/libreremo_bot.py @@ -1,54 +1,44 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -from telegram.ext.updater import Updater -from telegram.update import Update +import glob +import logging + 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.messagehandler import MessageHandler from telegram.ext.conversationhandler import ConversationHandler -from telegram.ext.callbackqueryhandler import CallbackQueryHandler -from telegram.callbackquery import CallbackQuery from telegram.ext.filters import Filters -from libreremo_conf import TOKEN, CALIBRE_DIR, MIN_QUERY_LENGTH -import glob +from telegram.ext.messagehandler import MessageHandler +from telegram.ext.updater import Updater +from telegram.update import Update + import database_lib as DB -import logging +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) - + level=logging.INFO) updater = Updater(TOKEN, use_context=True, arbitrary_callback_data=True) db = DB.Database(CALIBRE_DIR + "metadata.db") def start(update: Update, context: CallbackContext): - update.message.reply_text(""" - Ciao, questo è il nuovo Bot di libreremo :), - al momento non funzionante e' attivo solo a scopo - di testing, ma restate connessi per aggiornamenti!! - """) -# qua puoi scaricare centinaia di testi -# universitari; /help se vuoi v.edere i -# comandi che puoi usare.""") + update.message.reply_text(txt.INTRO, parse_mode=ParseMode.HTML) def help(update: Update, context: CallbackContext): - update.message.reply_text("""Available Commands : - /search - /search_by_author - /search_by_class - /""") - - + 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="Corso di studio", callback_data="cds")]] + [InlineKeyboardButton(text="Autore", callback_data="autore")]] reply_markup = InlineKeyboardMarkup(keyboard) update.message.reply_text( - text="In base a cosa vuoi cercare il tuo libro?", + text="In base a cosa vuoi cercare il tuo libro?", reply_markup=reply_markup) return GET_RESOURCE_TYPE @@ -57,53 +47,49 @@ def _get_resource_type(update, context): query = update.callback_query context.user_data["resource"] = query.data context.bot.send_message( - chat_id = query.message.chat_id, - text = "quale {} stai cercando?" - .format(context.user_data["resource"])) + chat_id=query.message.chat_id, + text="quale {} stai cercando?".format(context.user_data["resource"])) return GET_RESOURCE def _get_resource(update, context): resource = update.message.text - result_list = []; - if (len(resource) <= MIN_QUERY_LENGTH): - update.message.reply_text(""" - scusa non ho capito cosa vuoi cercare, prova - ad inserire il titolo del libro per esteso, - cosa stai cercando?""") + 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"): + + 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"): + + elif context.user_data["resource"] == "autore": result_list = db.select_authors(resource) text = "Scegli uno di questi autori" handler = GET_AUTHOR - elif (context.user_data["resource"] == "cds"): -# result_list = db.select_class(resource) + elif context.user_data["resource"] == "cds": + # result_list = db.select_class(resource) text = "Scegli uno di questi corsi di studio" handler = GET_CDS logging.info("asked resource {res}: {txt}" - .format(res=context.user_data["resource"], txt=resource)) + .format(res=context.user_data["resource"], txt=resource)) if not result_list: logging.info("cannot found result for {}".format(resource)) - update.message.reply_text(""" - Mi dispiace non ho trovato niente, controlla....""") + 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, + text=text, reply_markup=reply_markup) - return handler - + return handler + def _get_author(update: Update, context: CallbackContext): query = update.callback_query @@ -111,41 +97,40 @@ def _get_author(update: Update, context: CallbackContext): if not result_list: logging.info("cannot find books for requested author") context.bot.send_message( - chat_id = query.message.chat_id, - text = "Mi dispiace ma non riesco a trovare libri per questo autore") + chat_id=query.message.chat_id, + text="Mi dispiace ma non riesco a trovare libri per questo autore") return ConversationHandler.END context.bot.send_message( - chat_id = query.message.chat_id, - text = "scegli uno di questi libri", - reply_markup = __format_reply_markup(result_list)) - return GET_BOOK + chat_id=query.message.chat_id, + text="scegli uno di questi libri", + reply_markup=__format_reply_markup(result_list)) + return GET_BOOK def _get_cds(update: Update, context: CallbackContext): query = update.callback_query -# result_list = db.select_books_by_cds(query) + # result_list = db.select_books_by_cds(query) context.bot.send_message( - chat_id = query.message.chat_id, - text = "scegli uno di questi libri", - reply_markup = reply_markup) - return GET_BOOK + chat_id=query.message.chat_id, + text="scegli uno di questi libri") + return GET_BOOK def _get_book(update: Update, context: CallbackContext): query = update.callback_query chat_id = query.message.chat_id query.message.reply_text( - 'perfetto ti invio immediatamente il file! :)') + 'perfetto, ti invio immediatamente il file, abbi un attimo di pazienza se il libro non arriva subito') try: filepath = CALIBRE_DIR + query.data + "/*.pdf" for file in glob.glob(filepath): - with open(file, 'rb') as doc_pdf: + with open(file, 'rb') as doc_pdf: context.bot.send_document(chat_id, doc_pdf) logging.info("Sharing {}".format(file)) except FileNotFoundError: logging.info("cannot send {}".format(filepath)) query.message.reply_text( - "Mi dispiace non rieco a trovare il file, prova piu' tardi") + "Mi dispiace non rieco a trovare il file, prova piu' tardi") return ConversationHandler.END @@ -159,15 +144,18 @@ def search_by_title(update: Update, context: CallbackContext): 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 + 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 search_by_class(update: Update, context: CallbackContext): update.message.reply_text("di quale corso di studio stai cercando i libri?") context.user_data["resource"] = "cds" @@ -182,21 +170,26 @@ def unknown(update: Update, context: CallbackContext): def __format_reply_markup(list_of_res): return InlineKeyboardMarkup([ [InlineKeyboardButton( - text = res.format_text(), - callback_data = res.format_data())] - for res in list_of_res]) + text=res.format_text(), + callback_data=res.format_data())] + for res in list_of_res]) + +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...") + return ConversationHandler.END GET_RESOURCE_TYPE, ASK_RESOURCE, GET_RESOURCE, GET_BOOK, GET_AUTHOR, GET_CDS = range(6) cnv_handler = ConversationHandler( - entry_points = [CommandHandler('search', _ask_resource_type), - CommandHandler('search_by_title', search_by_title), - CommandHandler('search_by_author', search_by_author), - CommandHandler('search_by_class', search_by_class), - MessageHandler(Filters.text, search_by_title_default)], - states = { + entry_points=[CommandHandler('search', _ask_resource_type), + CommandHandler('search_by_title', search_by_title), + CommandHandler('search_by_author', search_by_author), + CommandHandler('search_by_class', search_by_class), + MessageHandler(Filters.text, search_by_title_default)], + states={ GET_RESOURCE_TYPE: [CallbackQueryHandler(_get_resource_type)], GET_RESOURCE: [MessageHandler(Filters.text, _get_resource)], GET_AUTHOR: [CallbackQueryHandler(_get_author)], @@ -207,12 +200,12 @@ cnv_handler = ConversationHandler( MessageHandler(Filters.command, _cnv_stop)], ) - -updater.dispatcher.add_handler(cnv_handler) updater.dispatcher.add_handler(CommandHandler('start', start)) updater.dispatcher.add_handler(CommandHandler('help', help)) -updater.dispatcher.add_handler(MessageHandler(Filters.text, unknown)) +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() diff --git a/libreremo_res.py b/libreremo_res.py index 1038f3b..e9fa5a9 100644 --- a/libreremo_res.py +++ b/libreremo_res.py @@ -10,11 +10,12 @@ class ResourceInterface: callable(subclass.format_data) or NotImplemented) + class Author(ResourceInterface): def __init__(self, author, sort): self.author = author - self.sort = sort + self.sort = sort def format_text(self): return self.author @@ -22,12 +23,13 @@ class Author(ResourceInterface): def format_data(self): return self.sort + class Book(ResourceInterface): def __init__(self, title, author, file): self.title = title self.author = author - self.file = file + self.file = file def format_text(self): return self.title + " - " + self.author @@ -35,11 +37,12 @@ class Book(ResourceInterface): def format_data(self): return self.file + class CorsoDiStudio(ResourceInterface): def __init__(self, cds): self.cds = cds - + def format_text(self): return self.cds @@ -48,11 +51,11 @@ class CorsoDiStudio(ResourceInterface): def book_factory(cursor, row): - return Book(row[0], row[1], row[2]) + return Book(row[0], row[1], row[2]) + def author_factory(cursor, row): return Author(row[0], row[1]) -#def cds_factory(cursor, row): +# def cds_factory(cursor, row): # pass -