def decode_category_tag(x, for_json): from calibre.db.categories import Tag return Tag.from_dict(x)
def browse_category(self, category, sort): categories = self.categories_cache() categories['virt_libs'] = {} if category not in categories: raise cherrypy.HTTPError(404, 'category not found') category_meta = self.db.field_metadata category_name = _( 'Virtual Libraries' ) if category == 'virt_libs' else category_meta[category]['name'] datatype = 'text' if category == 'virt_libs' else category_meta[ category]['datatype'] # See if we have any sub-categories to display. As we find them, add # them to the displayed set to avoid showing the same item twice uc_displayed = set() cats = [] for ucat in sorted(categories.keys(), key=sort_key): if len(categories[ucat]) == 0: continue if category == 'formats': continue meta = category_meta.get(ucat, None) if meta is None: continue if meta['kind'] != 'user': continue cat_len = len(category) if not (len(ucat) > cat_len and ucat.startswith(category + '.')): continue if ucat in self.icon_map: icon = '_' + quote(self.icon_map[ucat]) else: icon = category_icon_map['user:'******'.') if dot > 0: # More subcats cat = cat[:dot] if cat not in uc_displayed: cats.append((cat, ucat[:cat_len + dot], icon)) uc_displayed.add(cat) else: # This is the end of the chain cats.append((cat, ucat, icon)) uc_displayed.add(cat) cats = u'\n\n'.join([( u'<li><a title="{2} {0}" href="{3}/browse/category/{1}"> </a>' u'<img src="{3}{src}" alt="{0}" />' u'<span class="label">{0}</span>' u'</li>').format(xml(x, True), xml(quote(y)), xml(_('Browse books by')), self.opts.url_prefix, src='/browse/icon/' + z) for x, y, z in cats]) if cats: cats = (u'\n<div class="toplevel">\n' '{0}</div>').format(cats) script = 'toplevel();' else: script = 'true' # Now do the category items vls = self.db.prefs.get('virtual_libraries', {}) categories['virt_libs'] = sorted([Tag(k) for k, v in vls.iteritems()], key=lambda x: sort_key(x.name)) items = categories[category] sort = self.browse_sort_categories(items, sort) if not cats and len(items) == 1: # Only one item in category, go directly to book list html = get_category_items(category, items, datatype, self.opts.url_prefix) href = re.search(r'<a href="([^"]+)"', html) if href is not None: # cherrypy does not auto unquote params when using # InternalRedirect raise cherrypy.InternalRedirect(unquote(href.group(1))) if len(items) <= self.opts.max_opds_ungrouped_items: script = 'false' items = get_category_items(category, items, datatype, self.opts.url_prefix) else: getter = lambda x: unicode(getattr(x, 'sort', x.name)) starts = set([]) for x in items: val = getter(x) if not val: val = u'A' starts.add(val[0].upper()) category_groups = OrderedDict() for x in sorted(starts): category_groups[x] = len( [y for y in items if getter(y).upper().startswith(x)]) items = [( u'<h3 title="{0}"><a class="load_href" title="{0}"' u' href="{4}{3}"><strong>{0}</strong> [{2}]</a></h3><div>' u'<div class="loaded" style="display:none"></div>' u'<div class="loading"><img alt="{1}" src="{4}/static/loading.gif" /><em>{1}</em></div>' u'</div>').format( xml(s, True), xml(_('Loading, please wait')) + '…', unicode(c), xml( u'/browse/category_group/%s/%s' % (hexlify(category.encode('utf-8')), hexlify(s.encode('utf-8'))), True), self.opts.url_prefix) for s, c in category_groups.items()] items = '\n\n'.join(items) items = u'<div id="groups">\n{0}</div>'.format(items) if cats: script = 'toplevel();category(%s);' % script else: script = 'category(%s);' % script main = u''' <div class="category"> <h3>{0}</h3> <a class="navlink" href="{3}/browse" title="{2}">{2} ↑</a> {1} </div> '''.format(xml(_('Browsing by') + ': ' + category_name), cats + items, xml(_('Up'), True), self.opts.url_prefix) return self.browse_template(sort).format(title=category_name, script=script, main=main)
def decode_category_tag(x, for_json): from calibre.db.categories import Tag return Tag.from_dict(x)