2014-09-07 21:55:40 +00:00
|
|
|
"""Looking for books"""
|
|
|
|
|
2015-10-05 21:54:38 +00:00
|
|
|
# PYTHON STUFFS #######################################################
|
|
|
|
|
2014-12-17 06:32:34 +00:00
|
|
|
import urllib
|
2014-09-07 21:55:40 +00:00
|
|
|
|
2015-02-11 17:12:39 +00:00
|
|
|
from nemubot import context
|
2015-10-30 20:57:45 +00:00
|
|
|
from nemubot.exception import IMException
|
2015-01-03 19:34:44 +00:00
|
|
|
from nemubot.hooks import hook
|
|
|
|
from nemubot.tools import web
|
2014-09-07 21:55:40 +00:00
|
|
|
|
2014-09-26 16:00:22 +00:00
|
|
|
from more import Response
|
|
|
|
|
2014-11-13 01:51:49 +00:00
|
|
|
|
2015-10-05 21:54:38 +00:00
|
|
|
# LOADING #############################################################
|
|
|
|
|
2014-09-07 21:55:40 +00:00
|
|
|
def load(context):
|
2015-10-27 17:03:28 +00:00
|
|
|
if not context.config or "goodreadskey" not in context.config:
|
2015-06-03 20:07:06 +00:00
|
|
|
raise ImportError("You need a Goodreads API key in order to use this "
|
|
|
|
"module. Add it to the module configuration file:\n"
|
|
|
|
"<module name=\"books\" goodreadskey=\"XXXXXX\" />\n"
|
|
|
|
"Get one at https://www.goodreads.com/api/keys")
|
2014-09-07 21:55:40 +00:00
|
|
|
|
2014-11-13 01:51:49 +00:00
|
|
|
|
2015-10-05 21:54:38 +00:00
|
|
|
# MODULE CORE #########################################################
|
|
|
|
|
2014-09-16 18:20:37 +00:00
|
|
|
def get_book(title):
|
2014-11-13 01:51:49 +00:00
|
|
|
"""Retrieve a book from its title"""
|
|
|
|
response = web.getXML("https://www.goodreads.com/book/title.xml?key=%s&title=%s" %
|
2015-06-09 23:41:13 +00:00
|
|
|
(context.config["goodreadskey"], urllib.parse.quote(title)))
|
2015-10-25 17:50:18 +00:00
|
|
|
if response is not None and len(response.getElementsByTagName("book")):
|
|
|
|
return response.getElementsByTagName("book")[0]
|
2014-09-16 18:20:37 +00:00
|
|
|
else:
|
|
|
|
return None
|
|
|
|
|
2014-11-13 01:51:49 +00:00
|
|
|
|
2014-09-16 18:20:37 +00:00
|
|
|
def search_books(title):
|
2014-11-13 01:51:49 +00:00
|
|
|
"""Get a list of book matching given title"""
|
|
|
|
response = web.getXML("https://www.goodreads.com/search.xml?key=%s&q=%s" %
|
2015-06-09 23:41:13 +00:00
|
|
|
(context.config["goodreadskey"], urllib.parse.quote(title)))
|
2015-10-25 17:50:18 +00:00
|
|
|
if response is not None and len(response.getElementsByTagName("search")):
|
|
|
|
return response.getElementsByTagName("search")[0].getElementsByTagName("results")[0].getElementsByTagName("work")
|
2014-09-07 21:55:40 +00:00
|
|
|
else:
|
|
|
|
return []
|
|
|
|
|
2014-11-13 01:51:49 +00:00
|
|
|
|
2014-09-16 18:20:37 +00:00
|
|
|
def search_author(name):
|
2014-11-13 01:51:49 +00:00
|
|
|
"""Looking for an author"""
|
|
|
|
response = web.getXML("https://www.goodreads.com/api/author_url/%s?key=%s" %
|
2015-06-09 23:41:13 +00:00
|
|
|
(urllib.parse.quote(name), context.config["goodreadskey"]))
|
2015-10-25 17:50:18 +00:00
|
|
|
if response is not None and len(response.getElementsByTagName("author")) and response.getElementsByTagName("author")[0].hasAttribute("id"):
|
2014-11-13 01:51:49 +00:00
|
|
|
response = web.getXML("https://www.goodreads.com/author/show/%s.xml?key=%s" %
|
2015-10-25 17:50:18 +00:00
|
|
|
(urllib.parse.quote(response.getElementsByTagName("author")[0].getAttribute("id")), context.config["goodreadskey"]))
|
|
|
|
if response is not None and len(response.getElementsByTagName("author")):
|
|
|
|
return response.getElementsByTagName("author")[0]
|
2014-09-16 18:20:37 +00:00
|
|
|
return None
|
|
|
|
|
|
|
|
|
2015-10-05 21:54:38 +00:00
|
|
|
# MODULE INTERFACE ####################################################
|
|
|
|
|
2015-11-02 19:19:12 +00:00
|
|
|
@hook.command("book",
|
2015-10-05 21:54:38 +00:00
|
|
|
help="Get information about a book from its title",
|
|
|
|
help_usage={
|
|
|
|
"TITLE": "Get information about a book titled TITLE"
|
|
|
|
})
|
2014-09-07 21:55:40 +00:00
|
|
|
def cmd_book(msg):
|
2015-06-03 20:07:06 +00:00
|
|
|
if not len(msg.args):
|
2015-10-30 20:57:45 +00:00
|
|
|
raise IMException("please give me a title to search")
|
2014-09-07 21:55:40 +00:00
|
|
|
|
2015-06-03 20:07:06 +00:00
|
|
|
book = get_book(" ".join(msg.args))
|
2014-09-16 18:20:37 +00:00
|
|
|
if book is None:
|
2015-10-30 20:57:45 +00:00
|
|
|
raise IMException("unable to find book named like this")
|
2014-09-18 05:57:06 +00:00
|
|
|
res = Response(channel=msg.channel)
|
2015-10-25 17:50:18 +00:00
|
|
|
res.append_message("%s, written by %s: %s" % (book.getElementsByTagName("title")[0].firstChild.nodeValue,
|
|
|
|
book.getElementsByTagName("author")[0].getElementsByTagName("name")[0].firstChild.nodeValue,
|
|
|
|
web.striphtml(book.getElementsByTagName("description")[0].firstChild.nodeValue if book.getElementsByTagName("description")[0].firstChild else "")))
|
2014-09-16 18:20:37 +00:00
|
|
|
return res
|
|
|
|
|
2014-11-13 01:51:49 +00:00
|
|
|
|
2015-11-02 19:19:12 +00:00
|
|
|
@hook.command("search_books",
|
2015-10-05 21:54:38 +00:00
|
|
|
help="Search book's title",
|
|
|
|
help_usage={
|
|
|
|
"APPROX_TITLE": "Search for a book approximately titled APPROX_TITLE"
|
|
|
|
})
|
2014-09-16 18:20:37 +00:00
|
|
|
def cmd_books(msg):
|
2015-06-03 20:07:06 +00:00
|
|
|
if not len(msg.args):
|
2015-10-30 20:57:45 +00:00
|
|
|
raise IMException("please give me a title to search")
|
2014-09-16 18:20:37 +00:00
|
|
|
|
2015-06-03 20:07:06 +00:00
|
|
|
title = " ".join(msg.args)
|
2014-09-18 05:57:06 +00:00
|
|
|
res = Response(channel=msg.channel,
|
2014-11-13 01:51:49 +00:00
|
|
|
title="%s" % (title),
|
|
|
|
count=" (%d more books)")
|
2014-09-07 21:55:40 +00:00
|
|
|
|
2014-10-02 05:03:27 +00:00
|
|
|
for book in search_books(title):
|
2015-10-25 17:50:18 +00:00
|
|
|
res.append_message("%s, writed by %s" % (book.getElementsByTagName("best_book")[0].getElementsByTagName("title")[0].firstChild.nodeValue,
|
|
|
|
book.getElementsByTagName("best_book")[0].getElementsByTagName("author")[0].getElementsByTagName("name")[0].firstChild.nodeValue))
|
2014-09-07 21:55:40 +00:00
|
|
|
return res
|
2014-09-16 18:20:37 +00:00
|
|
|
|
2014-11-13 01:51:49 +00:00
|
|
|
|
2015-11-02 19:19:12 +00:00
|
|
|
@hook.command("author_books",
|
2015-10-05 21:54:38 +00:00
|
|
|
help="Looking for books writen by a given author",
|
|
|
|
help_usage={
|
|
|
|
"AUTHOR": "Looking for books writen by AUTHOR"
|
|
|
|
})
|
2014-09-16 18:20:37 +00:00
|
|
|
def cmd_author(msg):
|
2015-06-03 20:07:06 +00:00
|
|
|
if not len(msg.args):
|
2015-10-30 20:57:45 +00:00
|
|
|
raise IMException("please give me an author to search")
|
2014-09-16 18:20:37 +00:00
|
|
|
|
2015-10-25 17:50:18 +00:00
|
|
|
name = " ".join(msg.args)
|
|
|
|
ath = search_author(name)
|
|
|
|
if ath is None:
|
2015-10-30 20:57:45 +00:00
|
|
|
raise IMException("%s does not appear to be a published author." % name)
|
2015-10-25 17:50:18 +00:00
|
|
|
return Response([b.getElementsByTagName("title")[0].firstChild.nodeValue for b in ath.getElementsByTagName("book")],
|
2014-11-13 01:51:49 +00:00
|
|
|
channel=msg.channel,
|
2015-10-25 17:50:18 +00:00
|
|
|
title=ath.getElementsByTagName("name")[0].firstChild.nodeValue)
|