Switch to using string functions as methods

This commit is contained in:
Kovid Goyal 2016-04-04 15:52:40 +05:30
parent 1a28db1073
commit 05c637cba7
14 changed files with 85 additions and 80 deletions

View File

@ -43,13 +43,13 @@ default_sort['formats'] = 999
def field_sorter(field_metadata):
return def(field):
lvl = str.format('{:03d}', default_sort[field] or 998)
lvl = '{:03d}'.format(default_sort[field] or 998)
fm = (field_metadata[field] or {})[field] or {}
return lvl + (fm.name or 'zzzzz')
def execute_search(ev):
name, val = JSON.parse(ev.currentTarget.getAttribute('data-search'))
search = str.format('{}:"={}"', name, str.replace(val, '"', r'\"'))
search = '{}:"={}"'.format(name, str.replace(val, '"', r'\"'))
get_boss().ui.books_view.change_search(search)
def download_format(ev):
@ -62,13 +62,13 @@ def read_format(ev):
def render_metadata(mi, interface_data, table, field_list=None):
def allowed_fields(field):
if str.endswith(field, '_index'):
if field.endswith('_index'):
fm = interface_data.field_metadata[field[:-len('_index')]]
if fm and fm.datatype is 'series':
return False
if str.startswith(field, '#'):
if field.startswith('#'):
return True
if field in IGNORED_FIELDS or str.endswith(field, '_sort'):
if field in IGNORED_FIELDS or field.endswith('_sort'):
return False
return True
@ -82,7 +82,7 @@ def render_metadata(mi, interface_data, table, field_list=None):
if is_searchable:
table.lastChild.lastChild.appendChild(E.a(
data_search=JSON.stringify([is_searchable, v]), onclick=execute_search,
title=str.format(_('Click to see books with {0}: {1}'), name, v), href='javascript: void(0)', v))
title=_('Click to see books with {0}: {1}').format(name, v), href='javascript: void(0)', v))
else:
if v.appendChild:
table.lastChild.lastChild.appendChild(v)
@ -106,7 +106,7 @@ def render_metadata(mi, interface_data, table, field_list=None):
add_row(name, val, is_html=True)
return
if fm.is_multiple and fm.is_multiple.list_to_ui:
all_vals = filter(None, map(str.strip, str.split(val, fm.is_multiple.list_to_ui)))
all_vals = filter(None, map(str.strip, val.split(fm.is_multiple.list_to_ui)))
add_row(name, all_vals, is_searchable=field, join=fm.is_multiple.list_to_ui)
else:
add_row(name, val, is_searchable=field)
@ -124,13 +124,13 @@ def render_metadata(mi, interface_data, table, field_list=None):
td.appendChild(E.span(fmt, style='white-space: nowrap'))
if interface_data.input_formats[fmt] or interface_data.input_formats[fmt.replace('ORIGINAL_', '')]:
td.lastChild.appendChild(E.a(
title=str.format(_('Read this book in the {} format'), fmt),
title=_('Read this book in the {} format').format(fmt),
href='javascript:void(0)', style='padding-left: 1em',
E.i(class_='fa fa-book'),
onclick=read_format, data_format=fmt
))
td.lastChild.appendChild(E.a(
title=str.format(_('Download the {} format of this book'), fmt),
title=_('Download the {} format of this book').format(fmt),
href='javascript:void(0)', style='padding-left: 1em',
E.i(class_='fa fa-cloud-download'),
onclick=download_format, data_format=fmt
@ -156,7 +156,7 @@ def render_metadata(mi, interface_data, table, field_list=None):
idval = val[k]
x = url_map[k]
if isinstance(x, list) and x.length is 2:
td.appendChild(E.a(title=str.format('{}:{}', k, idval), target='_new', href=x[1], x[0]))
td.appendChild(E.a(title='{}:{}'.format(k, idval), target='_new', href=x[1], x[0]))
else:
td.appendChild(E.span(k, ':', idval))
if k is not keys[-1]:
@ -169,7 +169,7 @@ def render_metadata(mi, interface_data, table, field_list=None):
for k in val:
lang = mi.lang_names[k] or k
td.appendChild(E.a(lang,
title=str.format(_('Click to see books with language: {}'), lang), href='javascript: void(0)',
title=_('Click to see books with language: {}').format(lang), href='javascript: void(0)',
data_search=JSON.stringify([field, k]), onclick=execute_search
))
if k is not val[-1]:
@ -191,7 +191,7 @@ def render_metadata(mi, interface_data, table, field_list=None):
table.appendChild(E.tr(E.td(name + ':'), E.td()))
table.lastChild.lastChild.appendChild(E.span(ival, _(' of '), E.a(
data_search=JSON.stringify([field, val]), onclick=execute_search,
title=str.format(_('Click to see books with {0}: {1}'), name, val), href='javascript: void(0)', val)))
title=_('Click to see books with {0}: {1}').format(name, val), href='javascript: void(0)', val)))
def process_field(field, fm):
name = fm.name or field
@ -230,7 +230,7 @@ def render_metadata(mi, interface_data, table, field_list=None):
elif datatype is 'int' or datatype is 'float':
fmt = (fm.display or {}).number_format
if fmt:
val = str.format(fmt, val)
val = fmt.format(val)
else:
val += ''
add_row(name, val)
@ -347,13 +347,12 @@ class BookDetailsPanel:
self.current_book_id = int(book_id)
metadata = self.interface_data.metadata[book_id]
get_boss().ui.set_title(metadata.title)
cover_url = str.format('get/cover/{}/{}', book_id, self.interface_data['library_id'])
alt = str.format(_('{} by {}'), metadata['title'], metadata['authors'].join(' & '))
cover_url = 'get/cover/{}/{}'.format(book_id, self.interface_data['library_id'])
alt = _('{} by {}').format(metadata['title'], metadata['authors'].join(' & '))
imgdiv = E.div(
E.img(
src=cover_url, alt=alt, title=alt, data_title=metadata['title'], data_authors=metadata['authors'].join(' & '),
style=str.format(
'border-radius: 20px; max-width: calc(100vw - 2em); max-height: calc(100vh - 4ex - {}); display: block; width:auto; height:auto; border-radius: 20px', get_font_size('title')
style='border-radius: 20px; max-width: calc(100vw - 2em); max-height: calc(100vh - 4ex - {}); display: block; width:auto; height:auto; border-radius: 20px'.format(get_font_size('title')
))
)
imgdiv.firstChild.onerror = self.on_img_err.bind(self)
@ -365,8 +364,8 @@ class BookDetailsPanel:
))
container = c.lastChild.firstChild
read_button = create_button(_('Read'), 'book', self.read_book.bind(self), _('Read this book'))
download_button = create_button(_('Download'), 'cloud-download', self.download_book.bind(self), str.format(
_('Download this book in the {} format'), self.preferred_format(book_id)))
download_button = create_button(_('Download'), 'cloud-download', self.download_book.bind(self),
_('Download this book in the {} format').format(self.preferred_format(book_id)))
row = E.div(read_button, '\xa0\xa0\xa0', download_button, style='margin-bottom: 1ex')
if not metadata.formats or not metadata.formats.length:
row.style.display = 'none'
@ -385,7 +384,7 @@ class BookDetailsPanel:
return get_preferred_format(self.interface_data.metadata[book_id], self.interface_data.output_format, self.interface_data.input_formats)
def download_format(self, fmt):
window.location = str.format('get/{}/{}/{}', fmt, self.current_book_id, self.interface_data.library_id)
window.location = 'get/{}/{}/{}'.format(fmt, self.current_book_id, self.interface_data.library_id)
def download_book(self):
book_id = self.current_book_id

View File

@ -73,8 +73,8 @@ class Boss:
def onerror(self, msg, script_url, line_number, column_number, error_object):
console.log(error_object)
try:
fname = str.rpartition(script_url, '/')[-1] or script_url
msg = msg + '<br><span style="font-size:smaller">' + str.format('Error at {}:{}:{}', fname, line_number, column_number or '') + '</span>'
fname = script_url.rpartition('/')[-1] or script_url
msg = msg + '<br><span style="font-size:smaller">' + 'Error at {}:{}:{}'.format(fname, line_number, column_number or '') + '</span>'
details = ''
if error_object and error_object.stack:
details = error_object.stack
@ -105,12 +105,12 @@ class Boss:
self.read_ui.load_book(book_id, fmt, metadata)
def change_books(self, data):
data.search_result.sort = str.split(data.search_result.sort, ',')[:2].join(',')
data.search_result.sort_order = str.split(data.search_result.sort_order, ',')[:2].join(',')
data.search_result.sort = data.search_result.sort.split(',')[:2].join(',')
data.search_result.sort_order = data.search_result.sort_order.split(',')[:2].join(',')
sval = ''
for field, order in zip(str.split(data.search_result.sort, ','), str.split(data.search_result.sort_order, ',')):
for field, order in zip(data.search_result.sort.split(','), data.search_result.sort_order.split(',')):
sval += field + '.' + order + ','
get_session_data().set_library_option(self.interface_data.library_id, 'sort', str.rstrip(sval, ','))
get_session_data().set_library_option(self.interface_data.library_id, 'sort', sval.rstrip(','))
self.interface_data.metadata = data.metadata
self.interface_data.search_result = data.search_result
self.ui.refresh_books_view()

View File

@ -133,7 +133,7 @@ class SpinBox(ConfigItem):
)
container.appendChild(div)
control = div.lastChild
for attr in str.split('min max step'):
for attr in 'min max step'.split(' '):
val = item_data[attr]
if val is not undefined and val is not None:
control.setAttribute(attr, '' + val)
@ -202,7 +202,7 @@ class PrefsPanel:
def onfocus(name):
return def(ev):
c = self.container
div = c.querySelector(str.format('div[data-name="{}"]', name))
div = c.querySelector('div[data-name="{}"]'.format(name))
div.lastChild.style.display = 'block'
for item in data:

View File

@ -51,7 +51,7 @@ class SearchPanel:
type='search', autosave='search-for-books-in-main-calibre-booklist', name='search-books',
autocomplete='on', inputmode='latin',
title=_('Search for books'), placeholder=_('Enter the search query'), spellcheck='false',
style=str.format("flex-grow: 10; padding: {} 0.5em; margin-right: 0.5em", BUTTON_VPADDING)
style="flex-grow: 10; padding: {} 0.5em; margin-right: 0.5em".format(BUTTON_VPADDING)
),
search_button
))
@ -96,7 +96,7 @@ class SearchPanel:
self.currently_loading = None
sd = get_session_data()
query = {'library_id': self.interface_data.library_id}
for k in str.split('sort_tags_by partition_method collapse_at dont_collapse hide_empty_categories'):
for k in 'sort_tags_by partition_method collapse_at dont_collapse hide_empty_categories'.split(' '):
query[k] = sd.get(k) + ''
xhr = ajax('interface-data/tag-browser', self.on_data_fetched.bind(self), query=query, bypass_cache=False)
xhr.send()
@ -169,11 +169,11 @@ class SearchPanel:
data = node.data
tooltip = ''
if data.count is not undefined:
tooltip += '\n' + str.format(_('Number of books in this category: {}'), data.count)
tooltip += '\n' + _('Number of books in this category: {}').format(data.count)
if data.avg_rating is not undefined:
tooltip += '\n' + str.format(_('Average rating for books in this category: {:.1f}'), data.avg_rating)
tooltip += '\n' + _('Average rating for books in this category: {:.1f}').format(data.avg_rating)
div = E.div(
title=str.lstrip(tooltip),
title=tooltip.lstrip(),
style="display:flex; align-items: stretch",
E.div(class_='tag-name',
style='border-right:solid 1px currentColor; padding: 1ex; display:flex; align-items: center',
@ -237,19 +237,19 @@ class SearchPanel:
if letters_seen.length:
charclass = letters_seen.join('')
if category is 'authors':
expr = str.format(r'author_sort:"~(^[{0}])|(&\s*[{0}])"', charclass)
expr = r'author_sort:"~(^[{0}])|(&\s*[{0}])"'.format(charclass)
elif category is 'series':
expr = str.format(r'series_sort:"~^[{0}]"', charclass)
expr = r'series_sort:"~^[{0}]"'.format(charclass)
else:
expr = str.format(r'{0}:"~^[{1}]"', category, charclass)
expr = r'{0}:"~^[{1}]"'.format(category, charclass)
else:
expr = str.format('{}:false', category)
expr = '{}:false'.format(category)
elif category is 'news':
expr = str.format('tags:"={}"', item.name)
expr = 'tags:"={}"'.format(item.name)
else:
return str.format('{}:{}', category, search_state)
return '{}:{}'.format(category, search_state)
if 'false' in search_state:
expr = '(not ' + expr + ')'
@ -258,7 +258,7 @@ class SearchPanel:
category = 'tags' if item.category is 'news' else item.category
if item.name and item.name[0] is '★':
# Assume ratings
expr = str.format('{}:{}', category, item.name.length)
expr = '{}:{}'.format(category, item.name.length)
else:
fm = self.interface_data.field_metadata[item.category]
suffix = ':' if fm and fm.is_csp else ''
@ -270,7 +270,7 @@ class SearchPanel:
name = '.' + name
if search_state is 'plusplus' or search_state is 'minusminus':
name = '.' + name
expr = str.format('{}:"={}{}"', category, name, suffix)
expr = '{}:"={}{}"'.format(category, name, suffix)
if 'false' in search_state:
expr = '(not ' + expr + ')'
@ -299,7 +299,7 @@ class SearchPanel:
if data.count is not undefined:
items.append(_('Count: ') + data.count)
if data.avg_rating is not undefined:
items.append(str.format(_('Rating: {:.1f}'), data.avg_rating))
items.append(_('Rating: {:.1f}').format(data.avg_rating))
suffix = ''
if items.length:
suffix = ' [' + items.join(' ') + ']'
@ -332,7 +332,7 @@ class SearchPanel:
for text, search_type in items:
li = E.li(
style='display:flex; align-items: center; margin-bottom:0.5ex; padding: 0.5ex; cursor:pointer',
E.img(src=str.format('{}/{}.png', self.interface_data.icon_path, search_type), style='max-height: 2.5ex'),
E.img(src='{}/{}.png'.format(self.interface_data.icon_path, search_type), style='max-height: 2.5ex'),
E.span('\xa0' + text)
)
li.addEventListener('click', add_to_search(node, search_type))

View File

@ -4,7 +4,7 @@
DARK = '#39322B'
LIGHT = '#F6F3E9'
LIGHT_DARKER = '#b6b3a8'
LIGHT_GRADIENT = str.format('linear-gradient(to bottom, {}, {})', LIGHT, LIGHT_DARKER)
LIGHT_GRADIENT = 'linear-gradient(to bottom, {}, {})'.format(LIGHT, LIGHT_DARKER)
def get_color(name):
return {

View File

@ -71,8 +71,8 @@ class TopBar:
clear(left)
title_elem = 'a' if callable(title_action) else 'span'
left.appendChild(E.a(title=tooltip, E.i(class_='fa fa-' + icon_name + ' fa-fw')))
left.appendChild(E(title_elem, title, title=title_tooltip, class_='top-bar-title', style=str.format(
'margin-left: {0}; font-weight: bold; padding-top: {1}; padding-bottom: {1}; vertical-align: middle', self.SPACING, self.VSPACING)))
left.appendChild(E(title_elem, title, title=title_tooltip, class_='top-bar-title',
style='margin-left: {0}; font-weight: bold; padding-top: {1}; padding-bottom: {1}; vertical-align: middle'.format(self.SPACING, self.VSPACING)))
if bar is self.bar:
a = left.firstChild
if icon_name is 'heart':

View File

@ -172,16 +172,16 @@ class BooksView:
set_css(div, border='dashed 1px currentColor', border_radius='10px')
def cover_grid_item(self, book_id):
cover_url = str.format('get/thumb/{}/{}?sz={}x{}', book_id, self.interface_data['library_id'], THUMBNAIL_MAX_WIDTH, THUMBNAIL_MAX_HEIGHT)
cover_url = 'get/thumb/{}/{}?sz={}x{}'.format(book_id, self.interface_data['library_id'], THUMBNAIL_MAX_WIDTH, THUMBNAIL_MAX_HEIGHT)
metadata = self.interface_data['metadata'][book_id]
alt = str.format(_('{} by {}'), metadata['title'], metadata['authors'].join(' & '))
alt = _('{} by {}').format(metadata['title'], metadata['authors'].join(' & '))
img = E.img(src=cover_url, alt=alt, title=alt, data_title=metadata['title'], data_authors=metadata['authors'].join(' & '),
style='max-width: 100%; max-height: 100%; display: block; width:auto; height:auto; border-radius: 10px')
img.onerror = self.on_cover_grid_img_err.bind(self)
ans = E.div(
style=str.format(('margin: 10px; display: flex; align-content: flex-end; align-items: flex-end; justify-content: space-around;'
'width: 21vw; height: 28vw; max-width: {}px; max-height: {}px; min-width: {}px; min-height: {}px; cursor:pointer'),
style=('margin: 10px; display: flex; align-content: flex-end; align-items: flex-end; justify-content: space-around;'
'width: 21vw; height: 28vw; max-width: {}px; max-height: {}px; min-width: {}px; min-height: {}px; cursor:pointer').format(
THUMBNAIL_MAX_WIDTH, THUMBNAIL_MAX_HEIGHT, THUMBNAIL_MAX_WIDTH // 2, THUMBNAIL_MAX_HEIGHT // 2),
data_book_id=str(book_id),
img
@ -192,8 +192,8 @@ class BooksView:
# }}}
def sort_panel_data(self, create_item):
current_sorted_field = str.partition(self.interface_data.search_result.sort, ',')[0]
current_sorted_field_order = str.partition(self.interface_data.search_result.sort_order, ',')[0]
current_sorted_field = self.interface_data.search_result.sort.partition(',')[0]
current_sorted_field_order = self.interface_data.search_result.sort_order.partition(',')[0]
new_sort_order = 'desc' if current_sorted_field_order is 'asc' else 'asc'
if current_sorted_field is 'date':
current_sorted_field = 'timestamp'
@ -258,7 +258,7 @@ class BooksView:
window.scrollTo(0, 0)
elif end_type is not 'abort':
msg = xhr.error_html
if xhr.status is 400 and str.startswith(xhr.responseText, 'Invalid search expression:'):
if xhr.status is 400 and xhr.responseText.startswith('Invalid search expression:'):
msg = _('The search expression could not be parsed: ') + xhr.responseText
error_dialog(_('Could not change search query'), msg)

6
src/pyj/initialize.pyj Normal file
View File

@ -0,0 +1,6 @@
# vim:fileencoding=utf-8
# License: GPL v3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
from pythonize import strings
strings()

View File

@ -142,7 +142,7 @@ class DB:
req = self.idb.transaction(['files'], 'readwrite').objectStore('files').put(data, fname)
req.onsuccess = def(event): proceed()
req.onerror = def(event):
proceed(str.format(_('Failed to store book data ({0}) with error: {1}'), name, get_error_details(event)))
proceed(_('Failed to store book data ({0}) with error: {1}').format(name, get_error_details(event)))
def finish_book(self, book, proceed):
book.is_complete = True
@ -154,8 +154,8 @@ class DB:
def get_file(self, book, name, proceed):
key = file_store_name(book, name)
err = str.format(_(
'Failed to read the file {0} for the book {1} from the database'), name, book.metadata.title)
err = _(
'Failed to read the file {0} for the book {1} from the database').format(name, book.metadata.title)
self.do_op(['files'], key, err, def (result):
if not result:
self.show_error(_('Cannot read book'), err)

View File

@ -42,10 +42,10 @@ def load_resources(db, book, root_name, previous_resources, proceed):
w = book.manifest.cover_width or 600
h = book.manifest.cover_height or 800
ar = 'xMidYMid meet' # or 'none'
data = str.replace(data, '__ar__', ar)
data = str.replace(data, '__viewbox__', '0 0 ' + w + ' ' + h)
data = str.replace(data, '__width__', w + '')
data = str.replace(data, '__height__', h + '')
data = data.replace('__ar__', ar)
data = data.replace('__viewbox__', '0 0 ' + w + ' ' + h)
data = data.replace('__width__', w + '')
data = data.replace('__height__', h + '')
ans[name] = v'[data, mimetype]'
if type(data) is 'string':
find_virtualized_resources(data)
@ -131,7 +131,7 @@ def finalize_resources(book, root_name, resource_data):
break
if not resolved.length:
unresolved = [name for name in resource_data if name not in blob_url_map]
print(str.format('ERROR: Could not resolve all dependencies of {} because of a cyclic dependency. Remaining deps: {}', root_name, unresolved))
print('ERROR: Could not resolve all dependencies of {} because of a cyclic dependency. Remaining deps: {}'.format(root_name, unresolved))
# Add the items anyway, without resolving remaining deps
for name in resource_data:
if name not in blob_url_map:
@ -172,7 +172,7 @@ def process_stack(stack, tag_map, ns_map, load_required, onload):
attr = attr.replace('xlink:', '')
for a in (src.a or v'[]'):
if a[0] is attr:
loadable = str.startswith(a[1], 'blob:')
loadable = a[1].startswith('blob:')
break
if loadable:
load_required.add(node[0])

View File

@ -71,8 +71,8 @@ class ReadUI:
'book-id': (self.current_book_id + ''),
'panel':'book-details'
}))
a.textContent = str.format(_(
'Click to go back to the details page for: {}'), self.current_metadata.title)
a.textContent = _(
'Click to go back to the details page for: {}').format(self.current_metadata.title)
else:
a.textContent = ''
a.setAttribute('href', '')
@ -80,8 +80,8 @@ class ReadUI:
def init_ui(self):
div = self.show_stack(self.progress_id)
if self.current_metadata:
div.firstChild.textContent = str.format(_(
'Downloading {0} for offline reading, please wait...'), self.current_metadata.title)
div.firstChild.textContent = _(
'Downloading {0} for offline reading, please wait...').format(self.current_metadata.title)
else:
div.firstChild.textContent = ''
pr = div.firstChild.nextSibling
@ -133,14 +133,14 @@ class ReadUI:
if end_type is 'abort':
return
if end_type is not 'load':
return self.show_error(_('Failed to load book manifest'), str.format(
_('Could not open {title} as book manifest failed to load, click "Show Details" for more information.'), title=self.current_metadata.title),
return self.show_error(_('Failed to load book manifest'),
_('Could not open {title} as book manifest failed to load, click "Show Details" for more information.').format(title=self.current_metadata.title),
xhr.error_html)
try:
manifest = JSON.parse(xhr.responseText)
except Exception as err:
return self.show_error(_('Failed to load book manifest'), str.format(
_('The manifest for {title} is not valid'), title=self.current_metadata.title),
return self.show_error(_('Failed to load book manifest'),
_('The manifest for {title} is not valid').format(title=self.current_metadata.title),
err.stack or err.toString())
if manifest.version != RENDER_VERSION:
return self.show_error(_('calibre upgraded!'), _(
@ -162,8 +162,7 @@ class ReadUI:
progress = document.getElementById(self.progress_id)
pbar = progress.firstChild.nextSibling
library_id, book_id, fmt = book.key
base_path = str.format(
'book-file/{}/{}/{}/{}/', encodeURIComponent(book_id), encodeURIComponent(fmt),
base_path = 'book-file/{}/{}/{}/{}/'.format(encodeURIComponent(book_id), encodeURIComponent(fmt),
encodeURIComponent(book.manifest.book_hash.size), encodeURIComponent(book.manifest.book_hash.mtime))
query = {'library_id': library_id}
progress_track = {}
@ -175,7 +174,7 @@ class ReadUI:
for name in progress_track:
x += progress_track[name]
pbar.setAttribute('value', x + '')
progress.lastChild.textContent = str.format(_('Downloaded {0}, {1} left'), human_readable(x), human_readable(total - x))
progress.lastChild.textContent = _('Downloaded {0}, {1} left').format(human_readable(x), human_readable(total - x))
def on_stored(err):
files_left.discard(this)
@ -184,7 +183,7 @@ class ReadUI:
if len(files_left):
return
if failed_files.length:
det = [str.format('<h4>{}</h4><div>{}</div><hr>', fname, err_html) for fname, err_html in failed_files].join('')
det = ['<h4>{}</h4><div>{}</div><hr>'.format(fname, err_html) for fname, err_html in failed_files].join('')
self.show_error(_('Could not download book'), _(
'Failed to download some book data, click "Show details" for more information'), det)
return

View File

@ -1,6 +1,7 @@
# vim:fileencoding=utf-8
# License: GPL v3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
import initialize # noqa: unused-import
from ajax import ajax
from elementmaker import E
from gettext import gettext as _, install

View File

@ -32,7 +32,7 @@ def parse_url_params(url=None, allow_multiple=False):
return ans
pairs = q.replace(/\+/g, " ").split("&")
for pair in pairs:
key, val = str.partition(pair, '=')[::2]
key, val = pair.partition('=')[::2]
key, val = decodeURIComponent(key), decodeURIComponent(val)
if allow_multiple:
if not Object.prototype.hasOwnProperty.call(ans, key):
@ -64,7 +64,7 @@ def fmt_sidx(val, fmt='{:.2f}', use_roman=True):
if use_roman:
return roman(val)
return int(val) + ''
return str.format(fmt, float(val))
return fmt.format(float(val))
def human_readable(size, sep=' '):
divisor, suffix = 1, "B"
@ -73,10 +73,10 @@ def human_readable(size, sep=' '):
divisor, suffix = (1 << (i * 10)), candidate
break
size = (float(size)/divisor) + ''
pos = str.find(size, ".")
pos = size.find(".")
if pos > -1:
size = size[:pos + 2]
if str.endswith(size, '.0'):
if size.endswith('.0'):
size = size[:-2]
return size + sep + suffix

View File

@ -11,7 +11,7 @@ BUTTON_VPADDING = '0.5ex'
def create_button(text, icon=None, action=None, tooltip=None):
cls = ''
if icon:
cls = str.format('fa fa-{} fa-lg', icon)
cls = 'fa fa-{} fa-lg'.format(icon)
text = '\xa0' + text
ans = E.button(E.i(class_=cls), text, class_='calibre-push-button', type='button', title=tooltip or '')
if action is not None:
@ -20,7 +20,7 @@ def create_button(text, icon=None, action=None, tooltip=None):
create_button.style = build_rule('button.calibre-push-button',
border_radius='1em', background_clip='padding-box', background_color=get_color('button-start'),
background_image=str.format('linear-gradient(to bottom, {}, {})', get_color('button-start'), get_color('button-end')),
background_image='linear-gradient(to bottom, {}, {})'.format(get_color('button-start'), get_color('button-end')),
padding=BUTTON_VPADDING + ' 1em', color=get_color('button-text'), cursor='pointer', font_size='inherit'
)
create_button.style += build_rule('button.calibre-push-button:hover', transform='scale(1.2)')