patternpythonMinor
Telegram Bot that retrieves book information from GoodReads
Viewed 0 times
goodreadsretrievesbookbottelegramthatfrominformation
Problem
The project below is about a Telegram bot that implements both inline and offline modes. The idea is to get a brief info about a book, searched by title(it's author, rating, short description). I decided to retrieve the info from GoodReads. Besides the parse implementation, I have trouble in correctly accessing the Telegram API. Every recommendation and criticism is welcomed!
The GoodReads access to retrieve data
Main implementation of the bot
```
import telebot
from telebot import types
import gd
token = '[data]'
bot = telebot.TeleBot(token)
@bot.message_handler(commands=['start']) # greeting
def send_welcome(message):
bot.reply_to(message.chat.id, "Hi! How are you?")
@bot.
The GoodReads access to retrieve data
import goodreads
from goodreads import client
import random
class GoodreadsBook():
def __init__(self):
self.client_key = "[data]"
self.client_secret = "[data]"
def authenticate(self):
self.auth_client = client.GoodreadsClient(self.client_key, self.client_secret)
def parse_book(self, book):
return {
'title': book_data.title,
'author': book_data.authors[0],
'rating': book_data.rating,
'review': book_data.review,
'cover': book_data.image_url,
'link': book_data.link
}
def book(self):
""" Get info about a random book """
max_book_num = 10 000 000
index = random.randint(1, max_book_num)
book = self.auth_client.book(index)
return parse_book(book)
def book_search(self, q, page=1, search_field='all'):
""" Get the most popular books for the given query. This will search all
books in the title/author/ISBN fields and show matches, sorted by
popularity on Goodreads.
:param q: query text
:param page: which page to return (default 1)
:param search_fields: field to search, one of 'title', 'author' or
'genre' (default is 'all')
"""
books = self.auth_client.search_books(str(q), page, search_field)
return map(parse_book, books)Main implementation of the bot
```
import telebot
from telebot import types
import gd
token = '[data]'
bot = telebot.TeleBot(token)
@bot.message_handler(commands=['start']) # greeting
def send_welcome(message):
bot.reply_to(message.chat.id, "Hi! How are you?")
@bot.
Solution
i = 0
for book in books:
title = book[i].title
info_dict['title'] = title
author = book[i].authors[0]
info_dict['author'] = author
rating = book[i].average_rating
info_dict['rating'] = rating
review = book[i].description
info_dict['review'] = review
cover = book[i].image_url
info_dict['cover'] = cover
link = book[i].link
info_dict['link'] = link
i += 1
book_list.append(info_dict)I don't really get this part, either the books objects got some weird structure, or it seems like (and most likely is) that each object in this collection got also information about the whole collection.
So this might be just replaced with:
for book in books:
book_list.append({
'title': book.title,
'author': book.authors[0],
'rating': book.rating,
'review': book.review,
'cover': book.image_url,
'link': book.link
})which you might want to replace with list comprehession if you want to:
book_list = [{'title': book.title,
'author': book.authors[0],
'rating': book.rating,
'review': book.review,
'cover': book.image_url,
'link': book.link
} for book in books]But if I'm wrong and this books got really weird structure you can simplify your code as:
for i, book in enumerate(books):
book_data = book[i]
book_list.append({
'title': book_data.title,
'author': book_data.authors[0],
'rating': book_data.rating,
'review': book_data.review,
'cover': book_data.image_url,
'link': book_data.link
})now your
random_book function can be prettified a bit as:def random_book():
index = random.randint(1, 1000000)
book = gc.book(index)
return {
'title': book_data.title,
'author': book_data.authors[0],
'rating': book_data.rating,
'review': book_data.review,
'cover': book_data.image_url,
'link': book_data.link
}Now as we can see, these both two functions are having deal with same structure, so you might want to create a parse function. And in the end your code will be like:
import random
from goodreads import client
client_key = "[redacted]"
client_secret = "[redacted]"
gc = client.GoodreadsClient(client_key, client_secret)
def parse_book(book):
return {
'title': book_data.title,
'author': book_data.authors[0],
'rating': book_data.rating,
'review': book_data.review,
'cover': book_data.image_url,
'link': book_data.link
}
def book_info(title):
books = gc.search_books(str(title), page=1, search_field='all')
return map(parse_book, books)
def random_book():
index = random.randint(1, 1000000)
book = gc.book(index)
return parse_book(book)Also in
random_book I would replace index = random.randint(1, 1000000) with a call that returns a number of books in goodreads (if there is such) so you wont get an error here.Code Snippets
i = 0
for book in books:
title = book[i].title
info_dict['title'] = title
author = book[i].authors[0]
info_dict['author'] = author
rating = book[i].average_rating
info_dict['rating'] = rating
review = book[i].description
info_dict['review'] = review
cover = book[i].image_url
info_dict['cover'] = cover
link = book[i].link
info_dict['link'] = link
i += 1
book_list.append(info_dict)for book in books:
book_list.append({
'title': book.title,
'author': book.authors[0],
'rating': book.rating,
'review': book.review,
'cover': book.image_url,
'link': book.link
})book_list = [{'title': book.title,
'author': book.authors[0],
'rating': book.rating,
'review': book.review,
'cover': book.image_url,
'link': book.link
} for book in books]for i, book in enumerate(books):
book_data = book[i]
book_list.append({
'title': book_data.title,
'author': book_data.authors[0],
'rating': book_data.rating,
'review': book_data.review,
'cover': book_data.image_url,
'link': book_data.link
})def random_book():
index = random.randint(1, 1000000)
book = gc.book(index)
return {
'title': book_data.title,
'author': book_data.authors[0],
'rating': book_data.rating,
'review': book_data.review,
'cover': book_data.image_url,
'link': book_data.link
}Context
StackExchange Code Review Q#145187, answer score: 2
Revisions (0)
No revisions yet.