mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
1) Add 'series_sort' virtual column.
2) fixed bug causing exceptions when using zero-parameter functions at the innermost position in the value stack.
This commit is contained in:
parent
ab19edb96f
commit
86d85fd06c
@ -1170,6 +1170,8 @@ class TagsModel(QAbstractItemModel): # {{{
|
||||
charclass = ''.join(letters_seen)
|
||||
if k == 'author_sort':
|
||||
expr = r'%s:"~(^[%s])|(&\s*[%s])"'%(k, charclass, charclass)
|
||||
elif k == 'series':
|
||||
expr = r'series_sort:"~^[%s]"'%(charclass)
|
||||
else:
|
||||
expr = r'%s:"~^[%s]"'%(k, charclass)
|
||||
if node_searches[tag_item.tag.state] == 'true':
|
||||
|
@ -172,11 +172,14 @@ def force_to_bool(val):
|
||||
|
||||
class CacheRow(list): # {{{
|
||||
|
||||
def __init__(self, db, composites, val):
|
||||
def __init__(self, db, composites, val, series_col, series_sort_col):
|
||||
self.db = db
|
||||
self._composites = composites
|
||||
list.__init__(self, val)
|
||||
self._must_do = len(composites) > 0
|
||||
self._series_col = series_col
|
||||
self._series_sort_col = series_sort_col
|
||||
self._series_sort = None
|
||||
|
||||
def __getitem__(self, col):
|
||||
if self._must_do:
|
||||
@ -191,12 +194,19 @@ class CacheRow(list): # {{{
|
||||
elif col in self._composites:
|
||||
is_comp = True
|
||||
if is_comp:
|
||||
id = list.__getitem__(self, 0)
|
||||
id_ = list.__getitem__(self, 0)
|
||||
self._must_do = False
|
||||
mi = self.db.get_metadata(id, index_is_id=True,
|
||||
mi = self.db.get_metadata(id_, index_is_id=True,
|
||||
get_user_categories=False)
|
||||
for c in self._composites:
|
||||
self[c] = mi.get(self._composites[c])
|
||||
if col == self._series_sort_col and self._series_sort is None:
|
||||
if self[self._series_col]:
|
||||
self._series_sort = title_sort(self[self._series_col])
|
||||
self[self._series_sort_col] = self._series_sort
|
||||
else:
|
||||
self._series_sort = ''
|
||||
self[self._series_sort_col] = ''
|
||||
return list.__getitem__(self, col)
|
||||
|
||||
def __getslice__(self, i, j):
|
||||
@ -226,6 +236,8 @@ class ResultCache(SearchQueryParser): # {{{
|
||||
for key in field_metadata:
|
||||
if field_metadata[key]['datatype'] == 'composite':
|
||||
self.composites[field_metadata[key]['rec_index']] = key
|
||||
self.series_col = field_metadata['series']['rec_index']
|
||||
self.series_sort_col = field_metadata['series_sort']['rec_index']
|
||||
self._data = []
|
||||
self._map = self._map_filtered = []
|
||||
self.first_sort = True
|
||||
@ -918,9 +930,11 @@ class ResultCache(SearchQueryParser): # {{{
|
||||
for id in ids:
|
||||
try:
|
||||
self._data[id] = CacheRow(db, self.composites,
|
||||
db.conn.get('SELECT * from meta2 WHERE id=?', (id,))[0])
|
||||
db.conn.get('SELECT * from meta2 WHERE id=?', (id,))[0],
|
||||
self.series_col, self.series_sort_col)
|
||||
self._data[id].append(db.book_on_device_string(id))
|
||||
self._data[id].append(self.marked_ids_dict.get(id, None))
|
||||
self._data[id].append(None)
|
||||
except IndexError:
|
||||
return None
|
||||
try:
|
||||
@ -935,9 +949,11 @@ class ResultCache(SearchQueryParser): # {{{
|
||||
self._data.extend(repeat(None, max(ids)-len(self._data)+2))
|
||||
for id in ids:
|
||||
self._data[id] = CacheRow(db, self.composites,
|
||||
db.conn.get('SELECT * from meta2 WHERE id=?', (id,))[0])
|
||||
db.conn.get('SELECT * from meta2 WHERE id=?', (id,))[0],
|
||||
self.series_col, self.series_sort_col)
|
||||
self._data[id].append(db.book_on_device_string(id))
|
||||
self._data[id].append(self.marked_ids_dict.get(id, None))
|
||||
self._data[id].append(None)
|
||||
self._map[0:0] = ids
|
||||
self._map_filtered[0:0] = ids
|
||||
|
||||
@ -962,11 +978,13 @@ class ResultCache(SearchQueryParser): # {{{
|
||||
temp = db.conn.get('SELECT * FROM meta2')
|
||||
self._data = list(itertools.repeat(None, temp[-1][0]+2)) if temp else []
|
||||
for r in temp:
|
||||
self._data[r[0]] = CacheRow(db, self.composites, r)
|
||||
self._data[r[0]] = CacheRow(db, self.composites, r,
|
||||
self.series_col, self.series_sort_col)
|
||||
for item in self._data:
|
||||
if item is not None:
|
||||
item.append(db.book_on_device_string(item[0]))
|
||||
item.append(None)
|
||||
item.append(None)
|
||||
|
||||
marked_col = self.FIELD_MAP['marked']
|
||||
for id_,val in self.marked_ids_dict.iteritems():
|
||||
|
@ -434,6 +434,8 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
||||
self.field_metadata.set_field_record_index('ondevice', base, prefer_custom=False)
|
||||
self.FIELD_MAP['marked'] = base = base+1
|
||||
self.field_metadata.set_field_record_index('marked', base, prefer_custom=False)
|
||||
self.FIELD_MAP['series_sort'] = base = base+1
|
||||
self.field_metadata.set_field_record_index('series_sort', base, prefer_custom=False)
|
||||
|
||||
script = '''
|
||||
DROP VIEW IF EXISTS meta2;
|
||||
|
@ -327,6 +327,16 @@ class FieldMetadata(dict):
|
||||
'is_custom':False,
|
||||
'is_category':False,
|
||||
'is_csp': False}),
|
||||
('series_sort', {'table':None,
|
||||
'column':None,
|
||||
'datatype':'text',
|
||||
'is_multiple':{},
|
||||
'kind':'field',
|
||||
'name':_('Series Sort'),
|
||||
'search_terms':['series_sort'],
|
||||
'is_custom':False,
|
||||
'is_category':False,
|
||||
'is_csp': False}),
|
||||
('sort', {'table':None,
|
||||
'column':None,
|
||||
'datatype':'text',
|
||||
|
@ -218,7 +218,7 @@ class _CompileParser(_Parser):
|
||||
|
||||
def expr(self, level):
|
||||
if self.compile_text:
|
||||
self.max_level = max(level, self.max_level)
|
||||
self.max_level = max(level+1, self.max_level)
|
||||
|
||||
if self.token_is_id():
|
||||
funcs = formatter_functions().get_functions()
|
||||
|
@ -12,6 +12,7 @@ import inspect, re, traceback
|
||||
|
||||
from calibre import human_readable
|
||||
from calibre.constants import DEBUG
|
||||
from calibre.ebooks.metadata import title_sort
|
||||
from calibre.utils.titlecase import titlecase
|
||||
from calibre.utils.icu import capitalize, strcmp, sort_key
|
||||
from calibre.utils.date import parse_date, format_date, now, UNDEFINED_DATE
|
||||
@ -836,6 +837,17 @@ class BuiltinOndevice(BuiltinFormatterFunction):
|
||||
return _('Yes')
|
||||
return ''
|
||||
|
||||
class BuiltinSeriesSort(BuiltinFormatterFunction):
|
||||
name = 'series_sort'
|
||||
arg_count = 0
|
||||
category = 'Get values from metadata'
|
||||
__doc__ = doc = _('booksize() -- return the series sort value')
|
||||
|
||||
def evaluate(self, formatter, kwargs, mi, locals):
|
||||
if mi.series:
|
||||
return title_sort(mi.series)
|
||||
return ''
|
||||
|
||||
class BuiltinHasCover(BuiltinFormatterFunction):
|
||||
name = 'has_cover'
|
||||
arg_count = 0
|
||||
@ -1149,8 +1161,8 @@ _formatter_builtins = [
|
||||
BuiltinListSort(), BuiltinListUnion(), BuiltinLookup(),
|
||||
BuiltinLowercase(), BuiltinMultiply(), BuiltinNot(),
|
||||
BuiltinOndevice(), BuiltinOr(), BuiltinPrint(), BuiltinRawField(),
|
||||
BuiltinRe(), BuiltinSelect(), BuiltinShorten(), BuiltinStrcat(),
|
||||
BuiltinStrcatMax(),
|
||||
BuiltinRe(), BuiltinSelect(), BuiltinSeriesSort(), BuiltinShorten(),
|
||||
BuiltinStrcat(), BuiltinStrcatMax(),
|
||||
BuiltinStrcmp(), BuiltinStrInList(), BuiltinStrlen(), BuiltinSubitems(),
|
||||
BuiltinSublist(),BuiltinSubstr(), BuiltinSubtract(), BuiltinSwapAroundComma(),
|
||||
BuiltinSwitch(), BuiltinTemplate(), BuiltinTest(), BuiltinTitlecase(),
|
||||
|
Loading…
x
Reference in New Issue
Block a user