mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 18:54:09 -04:00
Make searching on indentifiers work
This commit is contained in:
parent
c82ef56145
commit
3d1b02d10f
@ -418,9 +418,9 @@ class ResultCache(SearchQueryParser): # {{{
|
|||||||
return matches
|
return matches
|
||||||
|
|
||||||
def get_user_category_matches(self, location, query, candidates):
|
def get_user_category_matches(self, location, query, candidates):
|
||||||
res = set([])
|
matches = set([])
|
||||||
if self.db_prefs is None or len(query) < 2:
|
if self.db_prefs is None or len(query) < 2:
|
||||||
return res
|
return matches
|
||||||
user_cats = self.db_prefs.get('user_categories', [])
|
user_cats = self.db_prefs.get('user_categories', [])
|
||||||
c = set(candidates)
|
c = set(candidates)
|
||||||
|
|
||||||
@ -435,10 +435,56 @@ class ResultCache(SearchQueryParser): # {{{
|
|||||||
for (item, category, ign) in user_cats[key]:
|
for (item, category, ign) in user_cats[key]:
|
||||||
s = self.get_matches(category, '=' + item, candidates=c)
|
s = self.get_matches(category, '=' + item, candidates=c)
|
||||||
c -= s
|
c -= s
|
||||||
res |= s
|
matches |= s
|
||||||
if query == 'false':
|
if query == 'false':
|
||||||
return candidates - res
|
return candidates - matches
|
||||||
return res
|
return matches
|
||||||
|
|
||||||
|
def get_keypair_matches(self, location, query, candidates):
|
||||||
|
matches = set([])
|
||||||
|
if query.find(':') >= 0:
|
||||||
|
q = [q.strip() for q in query.split(':')]
|
||||||
|
if len(q) != 2:
|
||||||
|
raise ParseException(query, len(query),
|
||||||
|
'Invalid query format for colon-separated search', self)
|
||||||
|
(keyq, valq) = q
|
||||||
|
keyq_mkind, keyq = self._matchkind(keyq)
|
||||||
|
valq_mkind, valq = self._matchkind(valq)
|
||||||
|
else:
|
||||||
|
keyq = keyq_mkind = ''
|
||||||
|
valq_mkind, valq = self._matchkind(query)
|
||||||
|
|
||||||
|
loc = self.field_metadata[location]['rec_index']
|
||||||
|
for id_ in candidates:
|
||||||
|
item = self._data[id_]
|
||||||
|
if item is None or item[loc] is None:
|
||||||
|
continue
|
||||||
|
pairs = [p.strip() for p in item[loc].split(',')]
|
||||||
|
for pair in pairs:
|
||||||
|
parts = pair.split(':')
|
||||||
|
if len(parts) != 2:
|
||||||
|
continue
|
||||||
|
k = parts[:1]
|
||||||
|
v = parts[1:]
|
||||||
|
if keyq and not _match(keyq, k, keyq_mkind):
|
||||||
|
continue
|
||||||
|
if valq and not _match(valq, v, valq_mkind):
|
||||||
|
continue
|
||||||
|
matches.add(id_)
|
||||||
|
return matches
|
||||||
|
|
||||||
|
def _matchkind(self, query):
|
||||||
|
matchkind = CONTAINS_MATCH
|
||||||
|
if (len(query) > 1):
|
||||||
|
if query.startswith('\\'):
|
||||||
|
query = query[1:]
|
||||||
|
elif query.startswith('='):
|
||||||
|
matchkind = EQUALS_MATCH
|
||||||
|
query = query[1:]
|
||||||
|
elif query.startswith('~'):
|
||||||
|
matchkind = REGEXP_MATCH
|
||||||
|
query = query[1:]
|
||||||
|
return matchkind, query
|
||||||
|
|
||||||
def get_matches(self, location, query, candidates=None,
|
def get_matches(self, location, query, candidates=None,
|
||||||
allow_recursion=True):
|
allow_recursion=True):
|
||||||
@ -504,22 +550,18 @@ class ResultCache(SearchQueryParser): # {{{
|
|||||||
len(item[loc].split(ms)) if item[loc] is not None else 0
|
len(item[loc].split(ms)) if item[loc] is not None else 0
|
||||||
return self.get_numeric_matches(location, query[1:],
|
return self.get_numeric_matches(location, query[1:],
|
||||||
candidates, val_func=vf)
|
candidates, val_func=vf)
|
||||||
|
# special case: identifiers. isbn is a special case within the case
|
||||||
|
if location == 'identifiers':
|
||||||
|
return self.get_keypair_matches(location, query, candidates)
|
||||||
|
if location == 'isbn':
|
||||||
|
return self.get_keypair_matches('identifiers', '=isbn:'+query, candidates)
|
||||||
|
|
||||||
# check for user categories
|
# check for user categories
|
||||||
if len(location) >= 2 and location.startswith('@'):
|
if len(location) >= 2 and location.startswith('@'):
|
||||||
return self.get_user_category_matches(location[1:], query.lower(),
|
return self.get_user_category_matches(location[1:], query.lower(),
|
||||||
candidates)
|
candidates)
|
||||||
# everything else, or 'all' matches
|
# everything else, or 'all' matches
|
||||||
matchkind = CONTAINS_MATCH
|
matchkind, query = self._matchkind(query)
|
||||||
if (len(query) > 1):
|
|
||||||
if query.startswith('\\'):
|
|
||||||
query = query[1:]
|
|
||||||
elif query.startswith('='):
|
|
||||||
matchkind = EQUALS_MATCH
|
|
||||||
query = query[1:]
|
|
||||||
elif query.startswith('~'):
|
|
||||||
matchkind = REGEXP_MATCH
|
|
||||||
query = query[1:]
|
|
||||||
if matchkind != REGEXP_MATCH:
|
if matchkind != REGEXP_MATCH:
|
||||||
# leave case in regexps because it can be significant e.g. \S \W \D
|
# leave case in regexps because it can be significant e.g. \S \W \D
|
||||||
query = icu_lower(query)
|
query = icu_lower(query)
|
||||||
|
@ -119,15 +119,6 @@ class FieldMetadata(dict):
|
|||||||
'search_terms':['formats', 'format'],
|
'search_terms':['formats', 'format'],
|
||||||
'is_custom':False,
|
'is_custom':False,
|
||||||
'is_category':True}),
|
'is_category':True}),
|
||||||
('identifiers', {'table':None,
|
|
||||||
'column':None,
|
|
||||||
'datatype':'text',
|
|
||||||
'is_multiple':',',
|
|
||||||
'kind':'field',
|
|
||||||
'name':_('Identifiers'),
|
|
||||||
'search_terms':['identifiers', 'identifier'],
|
|
||||||
'is_custom':False,
|
|
||||||
'is_category':True}),
|
|
||||||
('publisher', {'table':'publishers',
|
('publisher', {'table':'publishers',
|
||||||
'column':'name',
|
'column':'name',
|
||||||
'link_column':'publisher',
|
'link_column':'publisher',
|
||||||
@ -171,6 +162,15 @@ class FieldMetadata(dict):
|
|||||||
'search_terms':['tags', 'tag'],
|
'search_terms':['tags', 'tag'],
|
||||||
'is_custom':False,
|
'is_custom':False,
|
||||||
'is_category':True}),
|
'is_category':True}),
|
||||||
|
('identifiers', {'table':None,
|
||||||
|
'column':None,
|
||||||
|
'datatype':'text',
|
||||||
|
'is_multiple':',',
|
||||||
|
'kind':'field',
|
||||||
|
'name':_('Identifiers'),
|
||||||
|
'search_terms':['identifiers', 'identifier', 'isbn'],
|
||||||
|
'is_custom':False,
|
||||||
|
'is_category':True}),
|
||||||
('author_sort',{'table':None,
|
('author_sort',{'table':None,
|
||||||
'column':None,
|
'column':None,
|
||||||
'datatype':'text',
|
'datatype':'text',
|
||||||
@ -206,15 +206,6 @@ class FieldMetadata(dict):
|
|||||||
'search_terms':['cover'],
|
'search_terms':['cover'],
|
||||||
'is_custom':False,
|
'is_custom':False,
|
||||||
'is_category':False}),
|
'is_category':False}),
|
||||||
('flags', {'table':None,
|
|
||||||
'column':None,
|
|
||||||
'datatype':'text',
|
|
||||||
'is_multiple':None,
|
|
||||||
'kind':'field',
|
|
||||||
'name':None,
|
|
||||||
'search_terms':[],
|
|
||||||
'is_custom':False,
|
|
||||||
'is_category':False}),
|
|
||||||
('id', {'table':None,
|
('id', {'table':None,
|
||||||
'column':None,
|
'column':None,
|
||||||
'datatype':'int',
|
'datatype':'int',
|
||||||
@ -224,22 +215,13 @@ class FieldMetadata(dict):
|
|||||||
'search_terms':[],
|
'search_terms':[],
|
||||||
'is_custom':False,
|
'is_custom':False,
|
||||||
'is_category':False}),
|
'is_category':False}),
|
||||||
('isbn', {'table':None,
|
('last_modified', {'table':None,
|
||||||
'column':None,
|
'column':None,
|
||||||
'datatype':'text',
|
'datatype':'datetime',
|
||||||
'is_multiple':None,
|
'is_multiple':None,
|
||||||
'kind':'field',
|
'kind':'field',
|
||||||
'name':None,
|
'name':_('Date'),
|
||||||
'search_terms':['isbn'],
|
'search_terms':['last_modified'],
|
||||||
'is_custom':False,
|
|
||||||
'is_category':False}),
|
|
||||||
('lccn', {'table':None,
|
|
||||||
'column':None,
|
|
||||||
'datatype':'text',
|
|
||||||
'is_multiple':None,
|
|
||||||
'kind':'field',
|
|
||||||
'name':None,
|
|
||||||
'search_terms':[],
|
|
||||||
'is_custom':False,
|
'is_custom':False,
|
||||||
'is_category':False}),
|
'is_category':False}),
|
||||||
('ondevice', {'table':None,
|
('ondevice', {'table':None,
|
||||||
@ -305,15 +287,6 @@ class FieldMetadata(dict):
|
|||||||
'search_terms':['date'],
|
'search_terms':['date'],
|
||||||
'is_custom':False,
|
'is_custom':False,
|
||||||
'is_category':False}),
|
'is_category':False}),
|
||||||
('last_modified', {'table':None,
|
|
||||||
'column':None,
|
|
||||||
'datatype':'datetime',
|
|
||||||
'is_multiple':None,
|
|
||||||
'kind':'field',
|
|
||||||
'name':_('Date'),
|
|
||||||
'search_terms':['last_modified'],
|
|
||||||
'is_custom':False,
|
|
||||||
'is_category':False}),
|
|
||||||
('title', {'table':None,
|
('title', {'table':None,
|
||||||
'column':None,
|
'column':None,
|
||||||
'datatype':'text',
|
'datatype':'text',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user