def browse_matches(self, category=None, cid=None, list_sort=None): if list_sort: list_sort = unquote(list_sort) if not cid: raise cherrypy.HTTPError(404, "invalid category id: %r" % cid) categories = self.categories_cache() if category not in categories and category not in ("newest", "allbooks", "virt_libs"): raise cherrypy.HTTPError(404, "category not found") fm = self.db.field_metadata try: category_name = fm[category]["name"] dt = fm[category]["datatype"] except: if category not in ("newest", "allbooks", "virt_libs"): raise category_name = {"newest": _("Newest"), "allbooks": _("All books"), "virt_libs": _("Virtual Libraries")}[ category ] dt = None hide_sort = "true" if dt == "series" else "false" if category == "search": which = unhexlify(cid).decode("utf-8") try: ids = self.search_cache('search:"%s"' % which) except: raise cherrypy.HTTPError(404, "Search: %r not understood" % which) else: all_ids = self.search_cache("") if category == "newest": ids = all_ids hide_sort = "true" elif category == "allbooks": ids = all_ids elif category == "virt_libs": which = unhexlify(cid).decode("utf-8") vls = self.db.prefs.get("virtual_libraries", {}) ids = self.search_cache(vls[which]) else: if fm.get(category, {"datatype": None})["datatype"] == "composite": cid = cid.decode("utf-8") q = category if q == "news": q = "tags" ids = self.db.get_books_for_category(q, cid) ids = [x for x in ids if x in all_ids] items = [self.db.data.tablerow_for_id(x) for x in ids] if category == "newest": list_sort = "timestamp" if dt == "series": list_sort = category sort = self.browse_sort_book_list(items, list_sort) ids = [x[0] for x in items] html = render_book_list(ids, self.opts.url_prefix, suffix=_("in") + " " + category_name) return self.browse_template(sort, category=False).format( title=_("Books in") + " " + category_name, script="booklist(%s);" % hide_sort, main=html )
def browse_matches(self, category=None, cid=None, list_sort=None): if list_sort: list_sort = unquote(list_sort) if not cid: raise cherrypy.HTTPError(404, 'invalid category id: %r'%cid) categories = self.categories_cache() if category not in categories and \ category not in ('newest', 'allbooks'): raise cherrypy.HTTPError(404, 'category not found') fm = self.db.field_metadata try: category_name = fm[category]['name'] dt = fm[category]['datatype'] except: if category not in ('newest', 'allbooks'): raise category_name = { 'newest' : _('Newest'), 'allbooks' : _('All books'), }[category] dt = None hide_sort = 'true' if dt == 'series' else 'false' if category == 'search': which = unhexlify(cid).decode('utf-8') try: ids = self.search_cache('search:"%s"'%which) except: raise cherrypy.HTTPError(404, 'Search: %r not understood'%which) else: all_ids = self.search_cache('') if category == 'newest': ids = all_ids hide_sort = 'true' elif category == 'allbooks': ids = all_ids else: if fm.get(category, {'datatype':None})['datatype'] == 'composite': cid = cid.decode('utf-8') q = category if q == 'news': q = 'tags' ids = self.db.get_books_for_category(q, cid) ids = [x for x in ids if x in all_ids] items = [self.db.data._data[x] for x in ids] if category == 'newest': list_sort = 'timestamp' if dt == 'series': list_sort = category sort = self.browse_sort_book_list(items, list_sort) ids = [x[0] for x in items] html = render_book_list(ids, self.opts.url_prefix, suffix=_('in') + ' ' + category_name) return self.browse_template(sort, category=False).format( title=_('Books in') + " " +category_name, script='booklist(%s);'%hide_sort, main=html)
def browse_matches(self, category=None, cid=None, list_sort=None): if list_sort: list_sort = unquote(list_sort) if not cid: raise cherrypy.HTTPError(404, "invalid category id: %r" % cid) categories = self.categories_cache() if category not in categories and category not in ("newest", "allbooks", "virt_libs"): raise cherrypy.HTTPError(404, "category not found") fm = self.db.field_metadata try: category_name = fm[category]["name"] dt = fm[category]["datatype"] except: if category not in ("newest", "allbooks", "virt_libs"): raise category_name = {"newest": _("Newest"), "allbooks": _("All books"), "virt_libs": _("Virtual Libraries")}[ category ] dt = None hide_sort = "true" if dt == "series" else "false" if category == "search": which = unhexlify(cid).decode("utf-8") try: ids = self.search_cache('search:"%s"' % which) except: raise cherrypy.HTTPError(404, "Search: %r not understood" % which) else: all_ids = self.search_cache("") if category == "newest": ids = all_ids hide_sort = "true" elif category == "allbooks": ids = all_ids elif category == "virt_libs": which = unhexlify(cid).decode("utf-8") vls = self.db.prefs.get("virtual_libraries", {}) ids = self.search_cache(vls[which]) category_name = _("virtual library: ") + xml(which) if not ids: msg = _("The virtual library <b>%s</b> has no books.") % prepare_string_for_xml(which) if self.search_restriction: msg += " " + _( "This is probably because you have applied a virtual library" " to the content server in Preferences->Sharing over the net." " This virtual library is applied globally and combined with" " the current virtual library." ) return self.browse_template("name").format(title="", script="", main="<p>%s</p>" % msg) else: if fm.get(category, {"datatype": None})["datatype"] == "composite": cid = cid.decode("utf-8") q = category if q == "news": q = "tags" ids = self.db.get_books_for_category(q, cid) ids = [x for x in ids if x in all_ids] items = [self.db.data.tablerow_for_id(x) for x in ids] if category == "newest": list_sort = "timestamp" if dt == "series": list_sort = category sort = self.browse_sort_book_list(items, list_sort) ids = [x[0] for x in items] html = render_book_list(ids, self.opts.url_prefix, suffix=_("in") + " " + category_name) return self.browse_template(sort, category=False).format( title=_("Books in") + " " + category_name, script="booklist(%s);" % hide_sort, main=html )
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 browse_matches(self, category=None, cid=None, list_sort=None): if list_sort: list_sort = unquote(list_sort) if not cid: raise cherrypy.HTTPError(404, 'invalid category id: %r' % cid) categories = self.categories_cache() if category not in categories and \ category not in ('newest', 'allbooks', 'virt_libs'): raise cherrypy.HTTPError(404, 'category not found') fm = self.db.field_metadata try: category_name = fm[category]['name'] dt = fm[category]['datatype'] except: if category not in ('newest', 'allbooks', 'virt_libs'): raise category_name = { 'newest': _('Newest'), 'allbooks': _('All books'), 'virt_libs': _('Virtual Libraries'), }[category] dt = None hide_sort = 'true' if dt == 'series' else 'false' if category == 'search': which = unhexlify(cid).decode('utf-8') try: ids = self.search_cache('search:"%s"' % which) except: raise cherrypy.HTTPError(404, 'Search: %r not understood' % which) else: all_ids = self.search_cache('') if category == 'newest': ids = all_ids hide_sort = 'true' elif category == 'allbooks': ids = all_ids elif category == 'virt_libs': which = unhexlify(cid).decode('utf-8') vls = self.db.prefs.get('virtual_libraries', {}) ids = self.search_cache(vls[which]) category_name = _('virtual library: ') + xml(which) if not ids: msg = _('The virtual library <b>%s</b> has no books.' ) % prepare_string_for_xml(which) if self.search_restriction: msg += ' ' + _( 'This is probably because you have applied a virtual library' ' to the content server in Preferences->Sharing over the net.' ' This virtual library is applied globally and combined with' ' the current virtual library.') return self.browse_template('name').format( title='', script='', main='<p>%s</p>' % msg) else: if fm.get(category, {'datatype': None})['datatype'] == 'composite': cid = cid.decode('utf-8') q = category if q == 'news': q = 'tags' ids = self.db.get_books_for_category(q, cid) ids = [x for x in ids if x in all_ids] items = [self.db.data.tablerow_for_id(x) for x in ids] if category == 'newest': list_sort = 'timestamp' if dt == 'series': list_sort = category sort = self.browse_sort_book_list(items, list_sort) ids = [x[0] for x in items] html = render_book_list(ids, self.opts.url_prefix, suffix=_('in') + ' ' + category_name) return self.browse_template(sort, category=False).format( title=_('Books in') + " " + category_name, script='booklist(%s);' % hide_sort, main=html)
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 browse_matches(self, category=None, cid=None, list_sort=None): if list_sort: list_sort = unquote(list_sort) if not cid: raise cherrypy.HTTPError(404, 'invalid category id: %r'%cid) categories = self.categories_cache() if category not in categories and \ category not in ('newest', 'allbooks', 'virt_libs'): raise cherrypy.HTTPError(404, 'category not found') fm = self.db.field_metadata try: category_name = fm[category]['name'] dt = fm[category]['datatype'] except: if category not in ('newest', 'allbooks', 'virt_libs'): raise category_name = { 'newest' : _('Newest'), 'allbooks' : _('All books'), 'virt_libs': _('Virtual Libraries'), }[category] dt = None hide_sort = 'true' if dt == 'series' else 'false' if category == 'search': which = unhexlify(cid).decode('utf-8') try: ids = self.search_cache('search:"%s"'%which) except: raise cherrypy.HTTPError(404, 'Search: %r not understood'%which) else: all_ids = self.search_cache('') if category == 'newest': ids = all_ids hide_sort = 'true' elif category == 'allbooks': ids = all_ids elif category == 'virt_libs': which = unhexlify(cid).decode('utf-8') vls = self.db.prefs.get('virtual_libraries', {}) ids = self.search_cache(vls[which]) category_name = _('virtual library: ') + xml(which) if not ids: msg = _('The virtual library <b>%s</b> has no books.') % prepare_string_for_xml(which) if self.search_restriction: msg += ' ' + _( 'This is probably because you have applied a virtual library' ' to the content server in Preferences->Sharing over the net.' ' This virtual library is applied globally and combined with' ' the current virtual library.') return self.browse_template('name').format(title='', script='', main='<p>%s</p>'%msg) else: if fm.get(category, {'datatype':None})['datatype'] == 'composite': cid = cid.decode('utf-8') q = category if q == 'news': q = 'tags' ids = self.db.get_books_for_category(q, cid) ids = [x for x in ids if x in all_ids] items = [self.db.data.tablerow_for_id(x) for x in ids] if category == 'newest': list_sort = 'timestamp' if dt == 'series': list_sort = category sort = self.browse_sort_book_list(items, list_sort) ids = [x[0] for x in items] html = render_book_list(ids, self.opts.url_prefix, suffix=_('in') + ' ' + category_name) return self.browse_template(sort, category=False).format( title=_('Books in') + " " +category_name, script='booklist(%s);'%hide_sort, main=html)
def browse_matches(self, category=None, cid=None, list_sort=None): if list_sort: list_sort = unquote(list_sort) if not cid: raise cherrypy.HTTPError(404, 'invalid category id: %r' % cid) categories = self.categories_cache() if category not in categories and \ category not in ('newest', 'allbooks'): raise cherrypy.HTTPError(404, 'category not found') fm = self.db.field_metadata try: category_name = fm[category]['name'] dt = fm[category]['datatype'] except: if category not in ('newest', 'allbooks'): raise category_name = { 'newest': _('Newest'), 'allbooks': _('All books'), }[category] dt = None hide_sort = 'true' if dt == 'series' else 'false' if category == 'search': which = unhexlify(cid).decode('utf-8') try: ids = self.search_cache('search:"%s"' % which) except: raise cherrypy.HTTPError(404, 'Search: %r not understood' % which) else: all_ids = self.search_cache('') if category == 'newest': ids = all_ids hide_sort = 'true' elif category == 'allbooks': ids = all_ids else: if fm.get(category, {'datatype': None})['datatype'] == 'composite': cid = cid.decode('utf-8') q = category if q == 'news': q = 'tags' ids = self.db.get_books_for_category(q, cid) ids = [x for x in ids if x in all_ids] items = [self.db.data._data[x] for x in ids] if category == 'newest': list_sort = 'timestamp' if dt == 'series': list_sort = category sort = self.browse_sort_book_list(items, list_sort) ids = [x[0] for x in items] html = render_book_list(ids, self.opts.url_prefix, suffix=_('in') + ' ' + category_name) return self.browse_template(sort, category=False).format( title=_('Books in') + " " + category_name, script='booklist(%s);' % hide_sort, main=html)
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) # 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] print(items) 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: items = get_category_items(category, items, datatype, self.opts.url_prefix) else: getter = lambda x: unicode(getattr(x, 'sort', None) or 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) 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, main=main)