From 05c637cba7fc69086dc4d579776a1c021704557e Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 4 Apr 2016 15:52:40 +0530 Subject: [PATCH] Switch to using string functions as methods --- src/pyj/book_list/book_details.pyj | 39 +++++++++++++++--------------- src/pyj/book_list/boss.pyj | 12 ++++----- src/pyj/book_list/prefs.pyj | 4 +-- src/pyj/book_list/search.pyj | 30 +++++++++++------------ src/pyj/book_list/theme.pyj | 2 +- src/pyj/book_list/top_bar.pyj | 4 +-- src/pyj/book_list/views.pyj | 14 +++++------ src/pyj/initialize.pyj | 6 +++++ src/pyj/read_book/db.pyj | 6 ++--- src/pyj/read_book/resources.pyj | 12 ++++----- src/pyj/read_book/ui.pyj | 23 +++++++++--------- src/pyj/srv.pyj | 1 + src/pyj/utils.pyj | 8 +++--- src/pyj/widgets.pyj | 4 +-- 14 files changed, 85 insertions(+), 80 deletions(-) create mode 100644 src/pyj/initialize.pyj diff --git a/src/pyj/book_list/book_details.pyj b/src/pyj/book_list/book_details.pyj index d264567ebe..5dbd43718a 100644 --- a/src/pyj/book_list/book_details.pyj +++ b/src/pyj/book_list/book_details.pyj @@ -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 diff --git a/src/pyj/book_list/boss.pyj b/src/pyj/book_list/boss.pyj index 49657a1b5c..bd1661e51d 100644 --- a/src/pyj/book_list/boss.pyj +++ b/src/pyj/book_list/boss.pyj @@ -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 + '
' + str.format('Error at {}:{}:{}', fname, line_number, column_number or '') + '' + fname = script_url.rpartition('/')[-1] or script_url + msg = msg + '
' + 'Error at {}:{}:{}'.format(fname, line_number, column_number or '') + '' 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() diff --git a/src/pyj/book_list/prefs.pyj b/src/pyj/book_list/prefs.pyj index c0ae45186d..1aede339b3 100644 --- a/src/pyj/book_list/prefs.pyj +++ b/src/pyj/book_list/prefs.pyj @@ -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: diff --git a/src/pyj/book_list/search.pyj b/src/pyj/book_list/search.pyj index 43219891cb..172b9fb377 100644 --- a/src/pyj/book_list/search.pyj +++ b/src/pyj/book_list/search.pyj @@ -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)) diff --git a/src/pyj/book_list/theme.pyj b/src/pyj/book_list/theme.pyj index 6445075136..59d4ccc9fd 100644 --- a/src/pyj/book_list/theme.pyj +++ b/src/pyj/book_list/theme.pyj @@ -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 { diff --git a/src/pyj/book_list/top_bar.pyj b/src/pyj/book_list/top_bar.pyj index 51e4ba3cd0..a7f9ab4cb4 100644 --- a/src/pyj/book_list/top_bar.pyj +++ b/src/pyj/book_list/top_bar.pyj @@ -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': diff --git a/src/pyj/book_list/views.pyj b/src/pyj/book_list/views.pyj index f6ed818238..ef5978499a 100644 --- a/src/pyj/book_list/views.pyj +++ b/src/pyj/book_list/views.pyj @@ -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) diff --git a/src/pyj/initialize.pyj b/src/pyj/initialize.pyj new file mode 100644 index 0000000000..2ca5f6d179 --- /dev/null +++ b/src/pyj/initialize.pyj @@ -0,0 +1,6 @@ +# vim:fileencoding=utf-8 +# License: GPL v3 Copyright: 2016, Kovid Goyal + +from pythonize import strings + +strings() diff --git a/src/pyj/read_book/db.pyj b/src/pyj/read_book/db.pyj index daca9d6d98..723139bdab 100644 --- a/src/pyj/read_book/db.pyj +++ b/src/pyj/read_book/db.pyj @@ -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) diff --git a/src/pyj/read_book/resources.pyj b/src/pyj/read_book/resources.pyj index 8378b93291..a39d7ba0df 100644 --- a/src/pyj/read_book/resources.pyj +++ b/src/pyj/read_book/resources.pyj @@ -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]) diff --git a/src/pyj/read_book/ui.pyj b/src/pyj/read_book/ui.pyj index 137d97c35a..281cc6d284 100644 --- a/src/pyj/read_book/ui.pyj +++ b/src/pyj/read_book/ui.pyj @@ -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('

{}

{}

', fname, err_html) for fname, err_html in failed_files].join('') + det = ['

{}

{}

'.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 diff --git a/src/pyj/srv.pyj b/src/pyj/srv.pyj index 2da0623464..135925ad21 100644 --- a/src/pyj/srv.pyj +++ b/src/pyj/srv.pyj @@ -1,6 +1,7 @@ # vim:fileencoding=utf-8 # License: GPL v3 Copyright: 2015, Kovid Goyal +import initialize # noqa: unused-import from ajax import ajax from elementmaker import E from gettext import gettext as _, install diff --git a/src/pyj/utils.pyj b/src/pyj/utils.pyj index 83a1d47c3d..7372d3c5fd 100644 --- a/src/pyj/utils.pyj +++ b/src/pyj/utils.pyj @@ -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 diff --git a/src/pyj/widgets.pyj b/src/pyj/widgets.pyj index 32e5bb000c..209c3de3e0 100644 --- a/src/pyj/widgets.pyj +++ b/src/pyj/widgets.pyj @@ -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)')