Merge from trunk

This commit is contained in:
Charles Haley 2010-10-16 16:01:12 +01:00
commit 9462245394
2 changed files with 69 additions and 47 deletions

View File

@ -192,14 +192,19 @@ h2.library_name {
.toplevel li { .toplevel li {
margin: 0.75em; margin: 0.75em;
padding: 0.75em; padding: 0.75em;
text-align: center;
cursor: pointer; cursor: pointer;
font-size: larger;
border-radius: 15px; border-radius: 15px;
-moz-border-radius: 15px; -moz-border-radius: 15px;
-webkit-border-radius: 15px; -webkit-border-radius: 15px;
} }
.toplevel li img {
vertical-align: middle;
margin-right: 2em;
}
.toplevel li:hover { .toplevel li:hover {
background-color: #d6d3c9; background-color: #d6d3c9;
font-weight: bold; font-weight: bold;

View File

@ -16,6 +16,7 @@ from calibre import isbytestring, force_unicode, prepare_string_for_xml as xml
from calibre.utils.ordered_dict import OrderedDict from calibre.utils.ordered_dict import OrderedDict
from calibre.utils.filenames import ascii_filename from calibre.utils.filenames import ascii_filename
from calibre.utils.config import prefs from calibre.utils.config import prefs
from calibre.utils.magick import Image
from calibre.library.comments import comments_to_html from calibre.library.comments import comments_to_html
from calibre.library.server import custom_fields_to_display from calibre.library.server import custom_fields_to_display
from calibre.library.field_metadata import category_icon_map from calibre.library.field_metadata import category_icon_map
@ -193,50 +194,51 @@ class BrowseServer(object):
self.browse_search) self.browse_search)
connect('browse_details', base_href+'/details/{id}', connect('browse_details', base_href+'/details/{id}',
self.browse_details) self.browse_details)
connect('browse_category_icon', base_href+'/icon/{name}',
self.browse_icon)
# Templates {{{ # Templates {{{
def browse_template(self, sort, category=True, initial_search=''): def browse_template(self, sort, category=True, initial_search=''):
def generate(): if not hasattr(self, '__browse_template__') or \
scn = 'calibre_browse_server_sort_' self.opts.develop:
self.__browse_template__ = \
P('content_server/browse/browse.html', data=True).decode('utf-8')
if category: ans = self.__browse_template__
sort_opts = [('rating', _('Average rating')), ('name', scn = 'calibre_browse_server_sort_'
_('Name')), ('popularity', _('Popularity'))]
scn += 'category'
else:
scn += 'list'
fm = self.db.field_metadata
sort_opts, added = [], set([])
for x in fm.sortable_field_keys():
n = fm[x]['name']
if n not in added:
added.add(n)
sort_opts.append((x, n))
ans = P('content_server/browse/browse.html', if category:
data=True).decode('utf-8') sort_opts = [('rating', _('Average rating')), ('name',
ans = ans.replace('{sort_select_label}', xml(_('Sort by')+':')) _('Name')), ('popularity', _('Popularity'))]
ans = ans.replace('{sort_cookie_name}', scn) scn += 'category'
opts = ['<option %svalue="%s">%s</option>' % ( else:
'selected="selected" ' if k==sort else '', scn += 'list'
xml(k), xml(n), ) for k, n in fm = self.db.field_metadata
sorted(sort_opts, key=operator.itemgetter(1)) if k and n] sort_opts, added = [], set([])
ans = ans.replace('{sort_select_options}', ('\n'+' '*20).join(opts)) for x in fm.sortable_field_keys():
lp = self.db.library_path n = fm[x]['name']
if isbytestring(lp): if n not in added:
lp = force_unicode(lp, filesystem_encoding) added.add(n)
if isinstance(ans, unicode): sort_opts.append((x, n))
ans = ans.encode('utf-8')
ans = ans.replace('{library_name}', xml(os.path.basename(lp))) ans = ans.replace('{sort_select_label}', xml(_('Sort by')+':'))
ans = ans.replace('{library_path}', xml(lp, True)) ans = ans.replace('{sort_cookie_name}', scn)
ans = ans.replace('{initial_search}', initial_search) opts = ['<option %svalue="%s">%s</option>' % (
return ans 'selected="selected" ' if k==sort else '',
xml(k), xml(n), ) for k, n in
sorted(sort_opts, key=operator.itemgetter(1)) if k and n]
ans = ans.replace('{sort_select_options}', ('\n'+' '*20).join(opts))
lp = self.db.library_path
if isbytestring(lp):
lp = force_unicode(lp, filesystem_encoding)
if isinstance(ans, unicode):
ans = ans.encode('utf-8')
ans = ans.replace('{library_name}', xml(os.path.basename(lp)))
ans = ans.replace('{library_path}', xml(lp, True))
ans = ans.replace('{initial_search}', initial_search)
return ans
if self.opts.develop:
return generate()
if not hasattr(self, '__browse_template__'):
self.__browse_template__ = generate()
return self.__browse_template__ return self.__browse_template__
@property @property
@ -258,11 +260,24 @@ class BrowseServer(object):
# }}} # }}}
# Catalogs {{{ # Catalogs {{{
def browse_icon(self, name='blank.png'):
try:
data = I(name, data=True)
except:
raise cherrypy.HTTPError(404, 'no icon named: %r'%name)
img = Image()
img.load(data)
img.size = (48, 48)
cherrypy.response.headers['Content-Type'] = 'image/png'
cherrypy.response.headers['Last-Modified'] = self.last_modified(self.build_time)
return img.export('png')
def browse_toplevel(self): def browse_toplevel(self):
categories = self.categories_cache() categories = self.categories_cache()
category_meta = self.db.field_metadata category_meta = self.db.field_metadata
cats = [ cats = [
(_('Newest'), 'newest'), (_('Newest'), 'newest', 'blank.png'),
] ]
def getter(x): def getter(x):
@ -282,18 +297,20 @@ class BrowseServer(object):
continue continue
# get the icon files # get the icon files
if category in category_icon_map: if category in category_icon_map:
icon = I(category_icon_map[category]) icon = category_icon_map[category]
elif meta['is_custom']: elif meta['is_custom']:
icon = I(category_icon_map[':custom']) icon = category_icon_map[':custom']
elif meta['kind'] == 'user': elif meta['kind'] == 'user':
icon = I(category_icon_map[':user']) icon = category_icon_map[':user']
else: else:
icon = None # shouldn't get here icon = 'blank.png'
cats.append((meta['name'], category, icon))
cats.append((meta['name'], category)) cats = [('<li title="{2} {0}"><img src="{src}" alt="{0}" /> {0}'
cats = ['<li title="{2} {0}">{0}<span>/browse/category/{1}</span></li>'\ '<span>/browse/category/{1}</span></li>')
.format(xml(x, True), xml(quote(y)), xml(_('Browse books by'))) .format(xml(x, True), xml(quote(y)), xml(_('Browse books by')),
for x, y in cats] src='/browse/icon/'+z)
for x, y, z in cats]
main = '<div class="toplevel"><h3>{0}</h3><ul>{1}</ul></div>'\ main = '<div class="toplevel"><h3>{0}</h3><ul>{1}</ul></div>'\
.format(_('Choose a category to browse by:'), '\n\n'.join(cats)) .format(_('Choose a category to browse by:'), '\n\n'.join(cats))