diff --git a/src/calibre/db/backend.py b/src/calibre/db/backend.py index c2beb25e2e..0194cfc2ae 100644 --- a/src/calibre/db/backend.py +++ b/src/calibre/db/backend.py @@ -41,8 +41,7 @@ Differences in semantics from pysqlite: ''' - -class DynamicFilter(object): # {{{ +class DynamicFilter(object): # {{{ 'No longer used, present for legacy compatibility' @@ -57,7 +56,7 @@ class DynamicFilter(object): # {{{ self.ids = frozenset(ids) # }}} -class DBPrefs(dict): # {{{ +class DBPrefs(dict): # {{{ 'Store preferences as key:value pairs in the db' @@ -114,9 +113,10 @@ class DBPrefs(dict): # {{{ return default def set_namespaced(self, namespace, key, val): - if u':' in key: raise KeyError('Colons are not allowed in keys') - if u':' in namespace: raise KeyError('Colons are not allowed in' - ' the namespace') + if u':' in key: + raise KeyError('Colons are not allowed in keys') + if u':' in namespace: + raise KeyError('Colons are not allowed in the namespace') key = u'namespaced:%s:%s'%(namespace, key) self[key] = val @@ -170,7 +170,8 @@ def pynocase(one, two, encoding='utf-8'): return cmp(one.lower(), two.lower()) def _author_to_author_sort(x): - if not x: return '' + if not x: + return '' return author_to_author_sort(x.replace('|', ',')) def icu_collator(s1, s2): @@ -239,9 +240,9 @@ def AumSortedConcatenate(): # }}} -class Connection(apsw.Connection): # {{{ +class Connection(apsw.Connection): # {{{ - BUSY_TIMEOUT = 2000 # milliseconds + BUSY_TIMEOUT = 2000 # milliseconds def __init__(self, path): apsw.Connection.__init__(self, path) @@ -257,7 +258,7 @@ class Connection(apsw.Connection): # {{{ self.createscalarfunction('title_sort', title_sort, 1) self.createscalarfunction('author_to_author_sort', _author_to_author_sort, 1) - self.createscalarfunction('uuid4', lambda : str(uuid.uuid4()), + self.createscalarfunction('uuid4', lambda: str(uuid.uuid4()), 0) # Dummy functions for dynamically created filters @@ -380,7 +381,7 @@ class DB(object): self.initialize_custom_columns() self.initialize_tables() - def initialize_prefs(self, default_prefs): # {{{ + def initialize_prefs(self, default_prefs): # {{{ self.prefs = DBPrefs(self) if default_prefs is not None and not self._exists: @@ -493,7 +494,7 @@ class DB(object): self.prefs.set('user_categories', user_cats) # }}} - def initialize_custom_columns(self): # {{{ + def initialize_custom_columns(self): # {{{ with self.conn: # Delete previously marked custom columns for record in self.conn.get( @@ -634,11 +635,11 @@ class DB(object): self.custom_data_adapters = { 'float': adapt_number, - 'int': adapt_number, - 'rating':lambda x,d : x if x is None else min(10., max(0., float(x))), - 'bool': adapt_bool, + 'int': adapt_number, + 'rating':lambda x,d: x if x is None else min(10., max(0., float(x))), + 'bool': adapt_bool, 'comments': lambda x,d: adapt_text(x, {'is_multiple':False}), - 'datetime' : adapt_datetime, + 'datetime': adapt_datetime, 'text':adapt_text, 'series':adapt_text, 'enumeration': adapt_enum @@ -661,7 +662,7 @@ class DB(object): # }}} - def initialize_tables(self): # {{{ + def initialize_tables(self): # {{{ tables = self.tables = {} for col in ('title', 'sort', 'author_sort', 'series_index', 'comments', 'timestamp', 'pubdate', 'uuid', 'path', 'cover', @@ -866,8 +867,8 @@ class DB(object): Read all data from the db into the python in-memory tables ''' - with self.conn: # Use a single transaction, to ensure nothing modifies - # the db while we are reading + with self.conn: # Use a single transaction, to ensure nothing modifies + # the db while we are reading for table in self.tables.itervalues(): try: table.read(self) @@ -885,7 +886,7 @@ class DB(object): return fmt_path try: candidates = glob.glob(os.path.join(path, '*'+fmt)) - except: # If path contains strange characters this throws an exc + except: # If path contains strange characters this throws an exc candidates = [] if fmt and candidates and os.path.exists(candidates[0]): shutil.copyfile(candidates[0], fmt_path) @@ -954,7 +955,7 @@ class DB(object): if path != dest: os.rename(path, dest) except: - pass # Nothing too catastrophic happened, the cases mismatch, that's all + pass # Nothing too catastrophic happened, the cases mismatch, that's all else: windows_atomic_move.copy_path_to(path, dest) else: @@ -970,7 +971,7 @@ class DB(object): try: os.rename(path, dest) except: - pass # Nothing too catastrophic happened, the cases mismatch, that's all + pass # Nothing too catastrophic happened, the cases mismatch, that's all else: if use_hardlink: try: @@ -1021,7 +1022,7 @@ class DB(object): if not os.path.exists(tpath): os.makedirs(tpath) - if source_ok: # Migrate existing files + if source_ok: # Migrate existing files dest = os.path.join(tpath, 'cover.jpg') self.copy_cover_to(current_path, dest, windows_atomic_move=wam, use_hardlink=True) @@ -1064,7 +1065,7 @@ class DB(object): os.rename(os.path.join(curpath, oldseg), os.path.join(curpath, newseg)) except: - break # Fail silently since nothing catastrophic has happened + break # Fail silently since nothing catastrophic has happened curpath = os.path.join(curpath, newseg) def write_backup(self, path, raw): diff --git a/src/calibre/db/cache.py b/src/calibre/db/cache.py index 630757497b..0fa280d997 100644 --- a/src/calibre/db/cache.py +++ b/src/calibre/db/cache.py @@ -86,7 +86,7 @@ class Cache(object): # Assumption is that someone else will fix them if they change. self.field_metadata.remove_dynamic_categories() for user_cat in sorted(self._pref('user_categories', {}).iterkeys(), key=sort_key): - cat_name = '@' + user_cat # add the '@' to avoid name collision + cat_name = '@' + user_cat # add the '@' to avoid name collision self.field_metadata.add_user_category(label=cat_name, name=user_cat) # add grouped search term user categories @@ -118,7 +118,7 @@ class Cache(object): def field_metadata(self): return self.backend.field_metadata - def _get_metadata(self, book_id, get_user_categories=True): # {{{ + def _get_metadata(self, book_id, get_user_categories=True): # {{{ mi = Metadata(None, template_cache=self.formatter_template_cache) author_ids = self._field_ids_for('authors', book_id) aut_list = [self._author_data(i) for i in author_ids] @@ -403,16 +403,19 @@ class Cache(object): ''' if as_file: ret = SpooledTemporaryFile(SPOOL_SIZE) - if not self.copy_cover_to(book_id, ret): return + if not self.copy_cover_to(book_id, ret): + return ret.seek(0) elif as_path: pt = PersistentTemporaryFile('_dbcover.jpg') with pt: - if not self.copy_cover_to(book_id, pt): return + if not self.copy_cover_to(book_id, pt): + return ret = pt.name else: buf = BytesIO() - if not self.copy_cover_to(book_id, buf): return + if not self.copy_cover_to(book_id, buf): + return ret = buf.getvalue() if as_image: from PyQt4.Qt import QImage @@ -669,7 +672,7 @@ class Cache(object): else: v = sid = None if name.startswith('#') and sid is None: - sid = 1.0 # The value will be set to 1.0 in the db table + sid = 1.0 # The value will be set to 1.0 in the db table bimap[k] = v if sid is not None: simap[k] = sid @@ -808,7 +811,7 @@ class Cache(object): # }}} -class SortKey(object): # {{{ +class SortKey(object): # {{{ def __init__(self, fields, sort_keys, book_id): self.orders = tuple(1 if f[1] else -1 for f in fields) diff --git a/src/calibre/db/categories.py b/src/calibre/db/categories.py index f49789e16c..3f7bbb9e61 100644 --- a/src/calibre/db/categories.py +++ b/src/calibre/db/categories.py @@ -18,7 +18,7 @@ from calibre.utils.config_base import tweaks from calibre.utils.icu import sort_key from calibre.utils.search_query_parser import saved_searches -CATEGORY_SORTS = ('name', 'popularity', 'rating') # This has to be a tuple not a set +CATEGORY_SORTS = ('name', 'popularity', 'rating') # This has to be a tuple not a set class Tag(object): @@ -218,7 +218,7 @@ def get_categories(dbcache, sort='name', book_ids=None, icon_map=None): else: items.append(taglist[label][n]) # else: do nothing, to not include nodes w zero counts - cat_name = '@' + user_cat # add the '@' to avoid name collision + cat_name = '@' + user_cat # add the '@' to avoid name collision # Not a problem if we accumulate entries in the icon map if icon_map is not None: icon_map[cat_name] = icon_map['user:'] diff --git a/src/calibre/db/fields.py b/src/calibre/db/fields.py index e0074de7d1..20d0d75ff4 100644 --- a/src/calibre/db/fields.py +++ b/src/calibre/db/fields.py @@ -31,7 +31,7 @@ class Field(object): self.table_type = self.table.table_type self._sort_key = (sort_key if dt in ('text', 'series', 'enumeration') else lambda x: x) self._default_sort_key = '' - if dt in { 'int', 'float', 'rating' }: + if dt in {'int', 'float', 'rating'}: self._default_sort_key = 0 elif dt == 'bool': self._default_sort_key = None @@ -138,7 +138,7 @@ class OneToOneField(Field): return self.table.book_col_map.iterkeys() def sort_keys_for_books(self, get_metadata, lang_map, all_book_ids): - return {id_ : self._sort_key(self.table.book_col_map.get(id_, + return {id_: self._sort_key(self.table.book_col_map.get(id_, self._default_sort_key)) for id_ in all_book_ids} def iter_searchable_values(self, get_metadata, candidates, default_value=None): @@ -183,7 +183,7 @@ class CompositeField(OneToOneField): return ans def sort_keys_for_books(self, get_metadata, lang_map, all_book_ids): - return {id_ : sort_key(self.get_value_with_cache(id_, get_metadata)) for id_ in + return {id_: sort_key(self.get_value_with_cache(id_, get_metadata)) for id_ in all_book_ids} def iter_searchable_values(self, get_metadata, candidates, default_value=None): @@ -245,7 +245,7 @@ class OnDeviceField(OneToOneField): return iter(()) def sort_keys_for_books(self, get_metadata, lang_map, all_book_ids): - return {id_ : self.for_book(id_) for id_ in + return {id_: self.for_book(id_) for id_ in all_book_ids} def iter_searchable_values(self, get_metadata, candidates, default_value=None): @@ -280,12 +280,12 @@ class ManyToOneField(Field): return self.table.id_map.iterkeys() def sort_keys_for_books(self, get_metadata, lang_map, all_book_ids): - ans = {id_ : self.table.book_col_map.get(id_, None) + ans = {id_: self.table.book_col_map.get(id_, None) for id_ in all_book_ids} - sk_map = {cid : (self._default_sort_key if cid is None else + sk_map = {cid: (self._default_sort_key if cid is None else self._sort_key(self.table.id_map[cid])) for cid in ans.itervalues()} - return {id_ : sk_map[cid] for id_, cid in ans.iteritems()} + return {id_: sk_map[cid] for id_, cid in ans.iteritems()} def iter_searchable_values(self, get_metadata, candidates, default_value=None): cbm = self.table.col_book_map @@ -327,14 +327,14 @@ class ManyToManyField(Field): return self.table.id_map.iterkeys() def sort_keys_for_books(self, get_metadata, lang_map, all_book_ids): - ans = {id_ : self.table.book_col_map.get(id_, ()) + ans = {id_: self.table.book_col_map.get(id_, ()) for id_ in all_book_ids} all_cids = set() for cids in ans.itervalues(): all_cids = all_cids.union(set(cids)) - sk_map = {cid : self._sort_key(self.table.id_map[cid]) + sk_map = {cid: self._sort_key(self.table.id_map[cid]) for cid in all_cids} - return {id_ : (tuple(sk_map[cid] for cid in cids) if cids else + return {id_: (tuple(sk_map[cid] for cid in cids) if cids else (self._default_sort_key,)) for id_, cids in ans.iteritems()} @@ -369,9 +369,9 @@ class IdentifiersField(ManyToManyField): def sort_keys_for_books(self, get_metadata, lang_map, all_book_ids): 'Sort by identifier keys' - ans = {id_ : self.table.book_col_map.get(id_, ()) + ans = {id_: self.table.book_col_map.get(id_, ()) for id_ in all_book_ids} - return {id_ : (tuple(sorted(cids.iterkeys())) if cids else + return {id_: (tuple(sorted(cids.iterkeys())) if cids else (self._default_sort_key,)) for id_, cids in ans.iteritems()} @@ -397,9 +397,9 @@ class AuthorsField(ManyToManyField): def author_data(self, author_id): return { - 'name' : self.table.id_map[author_id], - 'sort' : self.table.asort_map[author_id], - 'link' : self.table.alink_map[author_id], + 'name': self.table.id_map[author_id], + 'sort': self.table.asort_map[author_id], + 'link': self.table.alink_map[author_id], } def category_sort_value(self, item_id, book_ids, lang_map): @@ -505,9 +505,9 @@ class TagsField(ManyToManyField): def create_field(name, table): cls = { - ONE_ONE : OneToOneField, - MANY_ONE : ManyToOneField, - MANY_MANY : ManyToManyField, + ONE_ONE: OneToOneField, + MANY_ONE: ManyToOneField, + MANY_MANY: ManyToManyField, }[table.table_type] if name == 'authors': cls = AuthorsField diff --git a/src/calibre/db/locking.py b/src/calibre/db/locking.py index d08c7b99fe..0791a5ac07 100644 --- a/src/calibre/db/locking.py +++ b/src/calibre/db/locking.py @@ -39,7 +39,7 @@ def create_locks(): l = SHLock() return RWLockWrapper(l), RWLockWrapper(l, is_shared=False) -class SHLock(object): # {{{ +class SHLock(object): # {{{ ''' Shareable lock class. Used to implement the Multiple readers-single writer paradigm. As best as I can tell, neither writer nor reader starvation @@ -191,7 +191,7 @@ class SHLock(object): # {{{ try: return self._free_waiters.pop() except IndexError: - return Condition(self._lock)#, verbose=True) + return Condition(self._lock) def _return_waiter(self, waiter): self._free_waiters.append(waiter) diff --git a/src/calibre/db/schema_upgrades.py b/src/calibre/db/schema_upgrades.py index f3ca6f9852..c8eaa748c7 100644 --- a/src/calibre/db/schema_upgrades.py +++ b/src/calibre/db/schema_upgrades.py @@ -172,7 +172,6 @@ class SchemaUpgrade(object): ''' ) - def upgrade_version_6(self): 'Show authors in order' self.conn.execute(''' @@ -337,7 +336,7 @@ class SchemaUpgrade(object): FROM {tn}; '''.format(tn=table_name, cn=column_name, - vcn=view_column_name, scn= sort_column_name)) + vcn=view_column_name, scn=sort_column_name)) self.conn.execute(script) def create_cust_tag_browser_view(table_name, link_table_name): diff --git a/src/calibre/db/search.py b/src/calibre/db/search.py index 57039e191d..c7fed18f9d 100644 --- a/src/calibre/db/search.py +++ b/src/calibre/db/search.py @@ -64,7 +64,7 @@ def _match(query, value, matchkind, use_primary_find_in_search=True): else: internal_match_ok = False for t in value: - try: ### ignore regexp exceptions, required because search-ahead tries before typing is finished + try: # ignore regexp exceptions, required because search-ahead tries before typing is finished t = icu_lower(t) if (matchkind == EQUALS_MATCH): if internal_match_ok: @@ -95,20 +95,20 @@ def _match(query, value, matchkind, use_primary_find_in_search=True): return False # }}} -class DateSearch(object): # {{{ +class DateSearch(object): # {{{ def __init__(self): self.operators = { - '=' : (1, self.eq), - '!=' : (2, self.ne), - '>' : (1, self.gt), - '>=' : (2, self.ge), - '<' : (1, self.lt), - '<=' : (2, self.le), + '=': (1, self.eq), + '!=': (2, self.ne), + '>': (1, self.gt), + '>=': (2, self.ge), + '<': (1, self.lt), + '<=': (2, self.le), } - self.local_today = { '_today', 'today', icu_lower(_('today')) } - self.local_yesterday = { '_yesterday', 'yesterday', icu_lower(_('yesterday')) } - self.local_thismonth = { '_thismonth', 'thismonth', icu_lower(_('thismonth')) } + self.local_today = {'_today', 'today', icu_lower(_('today'))} + self.local_yesterday = {'_yesterday', 'yesterday', icu_lower(_('yesterday'))} + self.local_thismonth = {'_thismonth', 'thismonth', icu_lower(_('thismonth'))} self.daysago_pat = re.compile(r'(%s|daysago|_daysago)$'%_('daysago')) def eq(self, dbdate, query, field_count): @@ -216,16 +216,16 @@ class DateSearch(object): # {{{ return matches # }}} -class NumericSearch(object): # {{{ +class NumericSearch(object): # {{{ def __init__(self): self.operators = { - '=':( 1, lambda r, q: r == q ), - '>':( 1, lambda r, q: r is not None and r > q ), - '<':( 1, lambda r, q: r is not None and r < q ), - '!=':( 2, lambda r, q: r != q ), - '>=':( 2, lambda r, q: r is not None and r >= q ), - '<=':( 2, lambda r, q: r is not None and r <= q ) + '=':(1, lambda r, q: r == q), + '>':(1, lambda r, q: r is not None and r > q), + '<':(1, lambda r, q: r is not None and r < q), + '!=':(2, lambda r, q: r != q), + '>=':(2, lambda r, q: r is not None and r >= q), + '<=':(2, lambda r, q: r is not None and r <= q) } def __call__(self, query, field_iter, location, datatype, candidates, is_many=False): @@ -267,7 +267,7 @@ class NumericSearch(object): # {{{ p, relop = self.operators['='] cast = int - if dt == 'rating': + if dt == 'rating': cast = lambda x: 0 if x is None else int(x) adjust = lambda x: x/2 elif dt in ('float', 'composite'): @@ -303,7 +303,7 @@ class NumericSearch(object): # {{{ # }}} -class BooleanSearch(object): # {{{ +class BooleanSearch(object): # {{{ def __init__(self): self.local_no = icu_lower(_('no')) @@ -324,27 +324,27 @@ class BooleanSearch(object): # {{{ for val, book_ids in field_iter(): val = force_to_bool(val) if not bools_are_tristate: - if val is None or not val: # item is None or set to false - if query in { self.local_no, self.local_unchecked, 'no', '_no', 'false' }: + if val is None or not val: # item is None or set to false + if query in {self.local_no, self.local_unchecked, 'no', '_no', 'false'}: matches |= book_ids - else: # item is explicitly set to true - if query in { self.local_yes, self.local_checked, 'yes', '_yes', 'true' }: + else: # item is explicitly set to true + if query in {self.local_yes, self.local_checked, 'yes', '_yes', 'true'}: matches |= book_ids else: if val is None: - if query in { self.local_empty, self.local_blank, 'empty', '_empty', 'false' }: + if query in {self.local_empty, self.local_blank, 'empty', '_empty', 'false'}: matches |= book_ids - elif not val: # is not None and false - if query in { self.local_no, self.local_unchecked, 'no', '_no', 'true' }: + elif not val: # is not None and false + if query in {self.local_no, self.local_unchecked, 'no', '_no', 'true'}: matches |= book_ids - else: # item is not None and true - if query in { self.local_yes, self.local_checked, 'yes', '_yes', 'true' }: + else: # item is not None and true + if query in {self.local_yes, self.local_checked, 'yes', '_yes', 'true'}: matches |= book_ids return matches # }}} -class KeyPairSearch(object): # {{{ +class KeyPairSearch(object): # {{{ def __call__(self, query, field_iter, candidates, use_primary_find): matches = set() @@ -547,11 +547,12 @@ class Parser(SearchQueryParser): field_metadata = {} for x, fm in self.field_metadata.iteritems(): - if x.startswith('@'): continue + if x.startswith('@'): + continue if fm['search_terms'] and x != 'series_sort': all_locs.add(x) field_metadata[x] = fm - if fm['datatype'] in { 'composite', 'text', 'comments', 'series', 'enumeration' }: + if fm['datatype'] in {'composite', 'text', 'comments', 'series', 'enumeration'}: text_fields.add(x) locations = all_locs if location == 'all' else {location} @@ -687,8 +688,8 @@ class Search(object): dbcache, all_book_ids, dbcache.pref('grouped_search_terms'), self.date_search, self.num_search, self.bool_search, self.keypair_search, - prefs[ 'limit_search_columns' ], - prefs[ 'limit_search_columns_to' ], self.all_search_locations, + prefs['limit_search_columns'], + prefs['limit_search_columns_to'], self.all_search_locations, virtual_fields) try: diff --git a/src/calibre/db/tables.py b/src/calibre/db/tables.py index bbc5e3bdef..fc62fbe951 100644 --- a/src/calibre/db/tables.py +++ b/src/calibre/db/tables.py @@ -82,7 +82,7 @@ class OneToOneTable(Table): self.metadata['column'], self.metadata['table'])): self.book_col_map[row[0]] = self.unserialize(row[1]) -class PathTable(OneToOneTable): +class PathTable(OneToOneTable): def set_path(self, book_id, path, db): self.book_col_map[book_id] = path diff --git a/src/calibre/db/view.py b/src/calibre/db/view.py index e0f99eede0..633fc6d9f9 100644 --- a/src/calibre/db/view.py +++ b/src/calibre/db/view.py @@ -60,10 +60,10 @@ class View(object): else: try: self._field_getters[idx] = { - 'id' : self._get_id, - 'au_map' : self.get_author_data, + 'id': self._get_id, + 'au_map': self.get_author_data, 'ondevice': self.get_ondevice, - 'marked' : self.get_marked, + 'marked': self.get_marked, }[col] except KeyError: self._field_getters[idx] = partial(self.get, col) diff --git a/src/calibre/db/write.py b/src/calibre/db/write.py index 29a27e16bf..87e7179661 100644 --- a/src/calibre/db/write.py +++ b/src/calibre/db/write.py @@ -417,7 +417,7 @@ def many_many(book_id_val_map, db, field, allow_case_change, *args): # }}} -def identifiers(book_id_val_map, db, field, *args): # {{{ +def identifiers(book_id_val_map, db, field, *args): # {{{ table = field.table updates = set() for book_id, identifiers in book_id_val_map.iteritems():