Compare commits

...

3 Commits

Author SHA1 Message Date
campi 00e016c968 bug 3 years ago
campi f921728e87 "bot main" 3 years ago
campi e0d0dba566 "new commit" 3 years ago

@ -6,7 +6,8 @@ import sqlite3 as sql3
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class Database():
class Database:
def __init__(self, filename): def __init__(self, filename):
self.filename = filename self.filename = filename
@ -17,7 +18,7 @@ class Database():
result_list = None result_list = None
try: try:
self.con = sql3.connect(self.filename) self.con = sql3.connect(self.filename)
self.con.row_factory = factory self.con.row_factory = factory
self.cur = self.con.cursor() self.cur = self.con.cursor()
logging.info("Connection to db open") logging.info("Connection to db open")
self.cur.execute(sql) self.cur.execute(sql)
@ -26,36 +27,37 @@ class Database():
logging.info("an error occured", error) logging.info("an error occured", error)
finally: finally:
if self.con: if self.con:
self.con.close() self.con.close()
logging.info("Connection to db closed") logging.info("Connection to db closed")
return result_list return result_list
def select_books_by_title(self, query): def select_books_by_title(self, query):
query = self.__format_query(query) query = format_query(query)
sql = f""" sql = f"""
SELECT title, author_sort, path FROM books SELECT title, author_sort, path FROM books
WHERE title LIKE '{query}'; 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): def select_books_by_author(self, query):
query = self.__format_query(query) query = format_query(query)
sql = f""" sql = f"""
SELECT title, author_sort, path FROM books SELECT title, author_sort, path FROM books
WHERE books.author_sort LIKE '%' || WHERE books.author_sort LIKE '%' ||
(SELECT sort FROM authors (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): def select_authors(self, query):
query = self.__format_query(query) query = format_query(query)
sql = f""" sql = f"""
SELECT name, sort FROM authors SELECT name, sort FROM authors
WHERE name LIKE '{query}'; WHERE name LIKE "{query}";
""" """
return self._execute(sql, res.author_factory) return self._execute(sql, res.author_factory)
def __format_query(self, query):
formatted_query = "%" + query.replace(" ", "%") + "%" def format_query(query):
return formatted_query formatted_query = "%" + query.replace(" ", "%") + "%"
return formatted_query

@ -0,0 +1,36 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
INTRO = """
Ciao, questo è il nuovo bot telegram di <b>Libreremo</b>, un progetto politico che da anni il collettivo universitario fiorentino porta avanti <b>distribuendo ogni anno centinaia di testi universitari GRATUITAMENTE</b> 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 questultima 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 lintero mondo dellistruzione e si fa particolarmente pesante in università.
Qua i nostri riferimenti social, stay tuned...
<a href="https://www.facebook.com/collettivodateneofirenze">Facebook</a>
<a href="https://www.instagram.com/collettivo_ateneo_firenze">Instagram</a>
<a href="mailto:colpol@inventati.org">Mail ColPol</a>
<a href=" mailto:collettivostumunifi@autistici.org">Mail Krisis</a>
<b>Per cominciare a cercare</b> 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 <b>Libreremo</b>, un progetto politico che da anni il collettivo universitario fiorentino porta avanti <b>distribuendo ogni anno centinaia di testi universitari GRATUITAMENTE</b> per contrastare la mercificazione della cultura e il carolibri.
<b>Per cominciare a cercare</b> 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"

@ -1,156 +1,159 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from telegram.ext.updater import Updater import glob
from telegram.update import Update import logging
import os.path
import urllib3
from telegram import InlineKeyboardButton, InlineKeyboardMarkup from telegram import InlineKeyboardButton, InlineKeyboardMarkup
from telegram import ParseMode
from telegram.ext.callbackcontext import CallbackContext from telegram.ext.callbackcontext import CallbackContext
from telegram.ext.callbackqueryhandler import CallbackQueryHandler
from telegram.ext.commandhandler import CommandHandler from telegram.ext.commandhandler import CommandHandler
from telegram.ext.messagehandler import MessageHandler
from telegram.ext.conversationhandler import ConversationHandler from telegram.ext.conversationhandler import ConversationHandler
from telegram.ext.callbackqueryhandler import CallbackQueryHandler
from telegram.callbackquery import CallbackQuery
from telegram.ext.filters import Filters from telegram.ext.filters import Filters
from libreremo_conf import TOKEN, CALIBRE_DIR, MIN_QUERY_LENGTH from telegram.ext.messagehandler import MessageHandler
import glob from telegram.ext.updater import Updater
import database_lib as DB from telegram.update import Update
import logging
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', import database_lib as DB
level=logging.INFO) 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
)
updater = Updater(TOKEN, use_context=True, arbitrary_callback_data=True)
db = DB.Database(CALIBRE_DIR + "metadata.db") db = DB.Database(CALIBRE_DIR + "metadata.db")
def start(update: Update, context: CallbackContext): def start(update: Update, context: CallbackContext):
update.message.reply_text(""" update.message.reply_text(txt.INTRO, parse_mode=ParseMode.HTML)
Ciao, questo è il nuovo Bot di libreremo :),
al momento non funzionante e' attivo solo a scopo
di testing, ma restate connessi per aggiornamenti!! def show_help(update: Update, context: CallbackContext):
""") update.message.reply_text(txt.HELP, parse_mode=ParseMode.HTML)
# qua puoi scaricare centinaia di testi
# universitari; /help se vuoi v.edere i
# comandi che puoi usare.""")
def help(update: Update, context: CallbackContext):
update.message.reply_text("""Available Commands :
/search
/search_by_author
/search_by_class
/""")
def _ask_resource_type(update, context): def _ask_resource_type(update, context):
keyboard = [[InlineKeyboardButton(text="Titolo", callback_data="titolo")], keyboard = [[InlineKeyboardButton(text="Titolo", callback_data="titolo")],
[InlineKeyboardButton(text="Autore", callback_data="autore")], [InlineKeyboardButton(text="Autore", callback_data="autore")],
[InlineKeyboardButton(text="Corso di studio", callback_data="cds")]] [InlineKeyboardButton(text="\u274C Annulla \u274C", callback_data="stop")]]
reply_markup = InlineKeyboardMarkup(keyboard) reply_markup = InlineKeyboardMarkup(keyboard)
update.message.reply_text( 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) reply_markup=reply_markup)
return GET_RESOURCE_TYPE return GET_RESOURCE_TYPE
def _get_resource_type(update, context): def _get_resource_type(update, context):
query = update.callback_query 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 context.user_data["resource"] = query.data
context.bot.send_message( query.edit_message_text(
chat_id = query.message.chat_id, text="quale <b>{}</b> stai cercando?".format(query.data),
text = "quale {} stai cercando?" parse_mode=ParseMode.HTML
.format(context.user_data["resource"])) )
return GET_RESOURCE return GET_RESOURCE
def _get_resource(update, context): def _get_resource(update, context):
resource = update.message.text resource = update.message.text
result_list = []; result_list = []
if (len(resource) <= MIN_QUERY_LENGTH): if len(resource) <= MIN_QUERY_LENGTH:
update.message.reply_text(""" update.message.reply_text(txt.SHORTQUERY)
scusa non ho capito cosa vuoi cercare, prova update.message.reply_text("Cosa stai cercando?")
ad inserire il titolo del libro per esteso,
cosa stai cercando?""")
return GET_RESOURCE return GET_RESOURCE
if (context.user_data["resource"] == "titolo"): if context.user_data["resource"] == "titolo":
result_list = db.select_books_by_title(resource) result_list = db.select_books_by_title(resource)
text = "Scegli uno di questi libri" text = "Scegli uno di questi libri"
handler = GET_BOOK handler = GET_BOOK
elif (context.user_data["resource"] == "autore"): elif context.user_data["resource"] == "autore":
result_list = db.select_authors(resource) result_list = db.select_authors(resource)
text = "Scegli uno di questi autori" text = "Scegli uno di questi autori"
handler = GET_AUTHOR handler = GET_AUTHOR
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}" 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: if not result_list:
logging.info("cannot found result for {}".format(resource)) logging.info("cannot found result for {}".format(resource))
update.message.reply_text(""" update.message.reply_text(txt.FILENOTFOUND, parse_mode=ParseMode.HTML)
Mi dispiace non ho trovato niente, controlla....""")
return ConversationHandler.END return ConversationHandler.END
reply_markup = __format_reply_markup(result_list) reply_markup = __format_reply_markup(result_list)
update.message.reply_text( update.message.reply_text(
text=text, text=text,
reply_markup=reply_markup) reply_markup=reply_markup)
return handler return handler
def _get_author(update: Update, context: CallbackContext): def _get_author(update: Update, context: CallbackContext):
query = update.callback_query query = update.callback_query
result_list = db.select_books_by_author(query.data) query.answer()
if not result_list: if query.data == "stop":
logging.info("cannot find books for requested author") query.edit_message_text("Ricerca annullata", None)
context.bot.send_message(
chat_id = query.message.chat_id,
text = "Mi dispiace ma non riesco a trovare libri per questo autore")
return ConversationHandler.END return ConversationHandler.END
context.bot.send_message( book_list = db.select_books_by_author(query.data)
chat_id = query.message.chat_id, if not book_list:
text = "scegli uno di questi libri", logging.info(f"cannot find books for author: {query.data}")
reply_markup = __format_reply_markup(result_list)) query.edit_message_text(
return GET_BOOK text="Mi dispiace ma non riesco a trovare libri per questo autore")
return ConversationHandler.END
query.edit_message_text(
def _get_cds(update: Update, context: CallbackContext): text="Questi sono i libri che abbiamo per <b>{}</b>".format(
query = update.callback_query "".join(query.data.split(",")[::-1])),
# result_list = db.select_books_by_cds(query) reply_markup=__format_reply_markup(book_list),
context.bot.send_message( parse_mode=ParseMode.HTML
chat_id = query.message.chat_id, )
text = "scegli uno di questi libri", return GET_BOOK
reply_markup = reply_markup)
return GET_BOOK
def _get_book(update: Update, context: CallbackContext): def _get_book(update: Update, context: CallbackContext):
query = update.callback_query 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 chat_id = query.message.chat_id
query.edit_message_reply_markup()
query.message.reply_text(
"Hai scelto: <b>{}</b>".format("(".join(
query.data.split("/", 1)[1]
.split("(")[:-1])),
parse_mode=ParseMode.HTML
)
query.message.reply_text( query.message.reply_text(
'perfetto ti invio immediatamente il file! :)') '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: try:
filepath = CALIBRE_DIR + query.data + "/*.pdf" for file in glob.glob(filepath + "/*.pdf"):
for file in glob.glob(filepath): with open(file, 'rb') as doc:
with open(file, 'rb') as doc_pdf: context.bot.send_document(chat_id, doc, timeout=120)
context.bot.send_document(chat_id, doc_pdf)
logging.info("Sharing {}".format(file)) logging.info("Sharing {}".format(file))
except FileNotFoundError: 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.info("cannot send {}".format(filepath))
logging.error(e)
query.message.reply_text( query.message.reply_text(
"Mi dispiace non rieco a trovare il file, prova piu' tardi") "Non riesco a mandarti il file, riprova più tardi")
return ConversationHandler.END return ConversationHandler.END
def _cnv_stop(update: Update, context: CallbackContext): def _cnv_stop(update: Update, context: CallbackContext):
update.message.reply_text("ciao") # context.bot.edit_message_reply_markup()
return ConversationHandler.END return ConversationHandler.END
@ -159,60 +162,71 @@ def search_by_title(update: Update, context: CallbackContext):
context.user_data["resource"] = "titolo" context.user_data["resource"] = "titolo"
return GET_RESOURCE return GET_RESOURCE
def search_by_title_default(update: Update, context: CallbackContext): def search_by_title_default(update: Update, context: CallbackContext):
context.user_data["resource"] = "titolo" context.user_data["resource"] = "titolo"
return GET_RESOURCE return _get_resource(update, context)
def search_by_author(update: Update, context: CallbackContext): def search_by_author(update: Update, context: CallbackContext):
update.message.reply_text("di quale autore stai cercando i libri?") update.message.reply_text("di quale autore stai cercando i libri?")
context.user_data["resource"] = "autore" context.user_data["resource"] = "autore"
return GET_RESOURCE 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"
return GET_RESOURCE
def unknown(update: Update, context: CallbackContext): def unknown(update: Update, context: CallbackContext):
update.message.reply_text( update.message.reply_text(
"Sorry '%s' is not a valid command" % update.message.text) "{} non è un comando valido, prova con /help".format(update.message.text))
def __format_reply_markup(list_of_res): def __format_reply_markup(list_of_res):
return InlineKeyboardMarkup([ inline_keyboard = [[InlineKeyboardButton(
[InlineKeyboardButton( text=res.format_text(), callback_data=res.format_data())]
text = res.format_text(), for res in list_of_res]
callback_data = res.format_data())] inline_keyboard.append([InlineKeyboardButton(
for res in list_of_res]) 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, GET_CDS = range(6)
GET_RESOURCE_TYPE, ASK_RESOURCE, GET_RESOURCE, GET_BOOK, GET_AUTHOR = range(5)
cnv_handler = ConversationHandler( cnv_handler = ConversationHandler(
entry_points = [CommandHandler('search', _ask_resource_type), entry_points=[CommandHandler('search', _ask_resource_type),
CommandHandler('search_by_title', search_by_title), CommandHandler('search_by_title', search_by_title),
CommandHandler('search_by_author', search_by_author), CommandHandler('search_by_author', search_by_author),
CommandHandler('search_by_class', search_by_class), MessageHandler(Filters.text, search_by_title_default)],
MessageHandler(Filters.text, search_by_title_default)], states={
states = { GET_RESOURCE_TYPE: [CallbackQueryHandler(_get_resource_type), MessageHandler(Filters.text, _cnv_stop)],
GET_RESOURCE_TYPE: [CallbackQueryHandler(_get_resource_type)],
GET_RESOURCE: [MessageHandler(Filters.text, _get_resource)], GET_RESOURCE: [MessageHandler(Filters.text, _get_resource)],
GET_AUTHOR: [CallbackQueryHandler(_get_author)], GET_AUTHOR: [CallbackQueryHandler(_get_author)],
GET_BOOK: [CallbackQueryHandler(_get_book)], GET_BOOK: [CallbackQueryHandler(_get_book)],
GET_CDS: [CallbackQueryHandler(_get_cds)]
}, },
fallbacks=[CommandHandler('stop', _cnv_stop), fallbacks=[CommandHandler('stop', _cnv_stop),
MessageHandler(Filters.command, _cnv_stop)], MessageHandler(Filters.command, _cnv_stop)],
) )
updater.dispatcher.add_handler(cnv_handler) def main():
updater.dispatcher.add_handler(CommandHandler('start', start)) updater = Updater(TOKEN, use_context=True, arbitrary_callback_data=True)
updater.dispatcher.add_handler(CommandHandler('help', help))
updater.dispatcher.add_handler(MessageHandler(Filters.text, unknown)) updater.dispatcher.add_handler(CommandHandler('start', start))
updater.dispatcher.add_handler(MessageHandler(Filters.command, unknown)) # Filters out unknown commands updater.dispatcher.add_handler(CommandHandler('help', show_help))
updater.dispatcher.add_handler(cnv_handler)
updater.start_polling() updater.dispatcher.add_handler(MessageHandler(Filters.command, unknown)) # Filters out unknown commands
updater.idle()
updater.dispatcher.add_error_handler(handle_error)
updater.start_polling()
updater.idle()
if __name__ == '__main__':
main()

@ -10,11 +10,12 @@ class ResourceInterface:
callable(subclass.format_data) or callable(subclass.format_data) or
NotImplemented) NotImplemented)
class Author(ResourceInterface): class Author(ResourceInterface):
def __init__(self, author, sort): def __init__(self, author, sort):
self.author = author self.author = author
self.sort = sort self.sort = sort
def format_text(self): def format_text(self):
return self.author return self.author
@ -22,12 +23,13 @@ class Author(ResourceInterface):
def format_data(self): def format_data(self):
return self.sort return self.sort
class Book(ResourceInterface): class Book(ResourceInterface):
def __init__(self, title, author, file): def __init__(self, title, author, file):
self.title = title self.title = title
self.author = author self.author = author
self.file = file self.file = file
def format_text(self): def format_text(self):
return self.title + " - " + self.author return self.title + " - " + self.author
@ -35,11 +37,12 @@ class Book(ResourceInterface):
def format_data(self): def format_data(self):
return self.file return self.file
class CorsoDiStudio(ResourceInterface): class CorsoDiStudio(ResourceInterface):
def __init__(self, cds): def __init__(self, cds):
self.cds = cds self.cds = cds
def format_text(self): def format_text(self):
return self.cds return self.cds
@ -48,11 +51,11 @@ class CorsoDiStudio(ResourceInterface):
def book_factory(cursor, row): 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): def author_factory(cursor, row):
return Author(row[0], row[1]) return Author(row[0], row[1])
#def cds_factory(cursor, row): # def cds_factory(cursor, row):
# pass # pass

Loading…
Cancel
Save