Content server AJAX interface: Add a dictionary that maps authors/tags/series/publishers/etc to URLs that list the books by that author/tag/publisher/etc.

This commit is contained in:
Kovid Goyal 2011-09-03 10:14:39 -06:00
parent 3b65dde564
commit 7af3b6e882

View File

@ -83,6 +83,10 @@ def category_url(prefix, cid):
def icon_url(prefix, name): def icon_url(prefix, name):
return absurl(prefix, '/browse/icon/'+name) return absurl(prefix, '/browse/icon/'+name)
def books_in_url(prefix, category, cid):
return absurl(prefix, '/ajax/books_in/%s/%s'%(
encode_name(category), encode_name(cid)))
# }}} # }}}
class AjaxServer(object): class AjaxServer(object):
@ -114,7 +118,7 @@ class AjaxServer(object):
# Get book metadata {{{ # Get book metadata {{{
def ajax_book_to_json(self, book_id): def ajax_book_to_json(self, book_id, get_category_urls=True):
mi = self.db.get_metadata(book_id, index_is_id=True) mi = self.db.get_metadata(book_id, index_is_id=True)
try: try:
mi.rating = mi.rating/2. mi.rating = mi.rating/2.
@ -151,18 +155,46 @@ class AjaxServer(object):
data['other_formats'] = {fmt: absurl(self.opts.url_prefix, u'/get/%s/%d'%(fmt, book_id)) for fmt data['other_formats'] = {fmt: absurl(self.opts.url_prefix, u'/get/%s/%d'%(fmt, book_id)) for fmt
in other_fmts} in other_fmts}
if get_category_urls:
category_urls = data['category_urls'] = {}
ccache = self.categories_cache()
for key in mi.all_field_keys():
fm = mi.metadata_for_field(key)
if (fm and fm['is_category'] and not fm['is_csp'] and
key != 'formats' and fm['datatype'] not in ['rating']):
categories = mi.get(key)
if isinstance(categories, basestring):
categories = [categories]
if categories is None:
categories = []
dbtags = {}
for category in categories:
for tag in ccache.get(key, []):
if tag.original_name == category:
dbtags[category] = books_in_url(self.opts.url_prefix,
tag.category if tag.category else key,
tag.original_name if tag.id is None else
unicode(tag.id))
break
category_urls[key] = dbtags
return data, mi.last_modified return data, mi.last_modified
@Endpoint(set_last_modified=False) @Endpoint(set_last_modified=False)
def ajax_book(self, book_id): def ajax_book(self, book_id, category_urls='true'):
''' '''
Return the metadata of the book as a JSON dictionary. Return the metadata of the book as a JSON dictionary.
If category_urls == 'true' the returned dictionary also contains a
mapping of category names to URLs that return the list of books in the
given category.
''' '''
cherrypy.response.timeout = 3600 cherrypy.response.timeout = 3600
try: try:
book_id = int(book_id) book_id = int(book_id)
data, last_modified = self.ajax_book_to_json(book_id) data, last_modified = self.ajax_book_to_json(book_id,
get_category_urls=category_urls.lower()=='true')
except: except:
raise cherrypy.HTTPError(404, 'No book with id: %r'%book_id) raise cherrypy.HTTPError(404, 'No book with id: %r'%book_id)
@ -172,7 +204,7 @@ class AjaxServer(object):
return data return data
@Endpoint(set_last_modified=False) @Endpoint(set_last_modified=False)
def ajax_books(self, ids=None): def ajax_books(self, ids=None, category_urls='true'):
''' '''
Return the metadata for a list of books specified as a comma separated Return the metadata for a list of books specified as a comma separated
list of ids. The metadata is returned as a dictionary mapping ids to list of ids. The metadata is returned as a dictionary mapping ids to
@ -192,9 +224,11 @@ class AjaxServer(object):
' of integers') ' of integers')
ans = {} ans = {}
lm = None lm = None
gcu = category_urls.lower()=='true'
for book_id in ids: for book_id in ids:
try: try:
data, last_modified = self.ajax_book_to_json(book_id) data, last_modified = self.ajax_book_to_json(book_id,
get_category_urls=gcu)
except: except:
ans[book_id] = None ans[book_id] = None
else: else:
@ -431,9 +465,9 @@ class AjaxServer(object):
'name':item_names.get(x, x.original_name), 'name':item_names.get(x, x.original_name),
'average_rating': x.avg_rating, 'average_rating': x.avg_rating,
'count': x.count, 'count': x.count,
'url': absurl(self.opts.url_prefix, '/ajax/books_in/%s/%s'%( 'url': books_in_url(self.opts.url_prefix,
encode_name(x.category if x.category else toplevel), x.category if x.category else toplevel,
encode_name(x.original_name if x.id is None else unicode(x.id)))), x.original_name if x.id is None else unicode(x.id)),
'has_children': x.original_name in children, 'has_children': x.original_name in children,
} for x in items] } for x in items]