mirror of
https://github.com/veekun/pokedex.git
synced 2024-08-20 18:16:34 +00:00
Refactored valid-type handling in lookup.
- User-specified types are now merged with code-enforced ones, rather than being blindly clobbered. - Prefix lookup now supports type prefixes.
This commit is contained in:
parent
954d997b0e
commit
b9a32beb35
1 changed files with 73 additions and 24 deletions
|
@ -226,6 +226,64 @@ class PokedexLookup(object):
|
||||||
return name
|
return name
|
||||||
|
|
||||||
|
|
||||||
|
def _apply_valid_types(self, name, valid_types):
|
||||||
|
"""Combines the enforced `valid_types` with any from the search string
|
||||||
|
itself and updates the query.
|
||||||
|
|
||||||
|
For example, a name of 'a,b:foo' and valid_types of b,c will search for
|
||||||
|
only `b`s named "foo".
|
||||||
|
|
||||||
|
Returns `(name, merged_valid_types, term)`, where `name` has had any type
|
||||||
|
prefix stripped, `merged_valid_types` combines the original
|
||||||
|
`valid_types` with the type prefix, and `term` is a query term for
|
||||||
|
limited to just the allowed types. If there are no type restrictions
|
||||||
|
at all, `term` will be None.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Remove any type prefix (pokemon:133) first
|
||||||
|
user_valid_types = []
|
||||||
|
if ':' in name:
|
||||||
|
prefix_chunk, name = name.split(':', 1)
|
||||||
|
name = name.strip()
|
||||||
|
|
||||||
|
prefixes = prefix_chunk.split(',')
|
||||||
|
user_valid_types = [_.strip() for _ in prefixes]
|
||||||
|
|
||||||
|
# Merge the valid types together. Only types that appear in BOTH lists
|
||||||
|
# may be used.
|
||||||
|
# As a special case, if the user asked for types that are explicitly
|
||||||
|
# forbidden, completely ignore what the user requested
|
||||||
|
combined_valid_types = []
|
||||||
|
if user_valid_types and valid_types:
|
||||||
|
combined_valid_types = list(
|
||||||
|
set(user_valid_types) & set(combined_valid_types)
|
||||||
|
)
|
||||||
|
|
||||||
|
if not combined_valid_types:
|
||||||
|
# No overlap! Just use the enforced ones
|
||||||
|
combined_valid_types = valid_types
|
||||||
|
else:
|
||||||
|
# One list or the other was blank, so just use the one that isn't
|
||||||
|
combined_valid_types = valid_types + user_valid_types
|
||||||
|
|
||||||
|
if not combined_valid_types:
|
||||||
|
# No restrictions
|
||||||
|
return name, [], None
|
||||||
|
|
||||||
|
# Construct the term
|
||||||
|
type_terms = []
|
||||||
|
final_valid_types = []
|
||||||
|
for valid_type in combined_valid_types:
|
||||||
|
table_name = self._parse_table_name(valid_type)
|
||||||
|
|
||||||
|
# Quietly ignore bogus valid_types; more likely to DTRT
|
||||||
|
if table_name:
|
||||||
|
final_valid_types.append(valid_type)
|
||||||
|
type_terms.append(whoosh.query.Term(u'table', table_name))
|
||||||
|
|
||||||
|
return name, final_valid_types, whoosh.query.Or(type_terms)
|
||||||
|
|
||||||
|
|
||||||
def _parse_table_name(self, name):
|
def _parse_table_name(self, name):
|
||||||
"""Takes a singular table name, table name, or table object and returns
|
"""Takes a singular table name, table name, or table object and returns
|
||||||
the table name.
|
the table name.
|
||||||
|
@ -318,20 +376,13 @@ class PokedexLookup(object):
|
||||||
exact = True
|
exact = True
|
||||||
form = None
|
form = None
|
||||||
|
|
||||||
# Remove any type prefix (pokemon:133) before constructing a query
|
# Pop off any type prefix and merge with valid_types
|
||||||
if ':' in name:
|
name, merged_valid_types, type_term = \
|
||||||
prefix_chunk, name = name.split(':', 1)
|
self._apply_valid_types(name, valid_types)
|
||||||
name = name.strip()
|
|
||||||
|
|
||||||
if not valid_types:
|
|
||||||
# Only use types from the query string if none were explicitly
|
|
||||||
# provided
|
|
||||||
prefixes = prefix_chunk.split(',')
|
|
||||||
valid_types = [_.strip() for _ in prefixes]
|
|
||||||
|
|
||||||
# Random lookup
|
# Random lookup
|
||||||
if name == 'random':
|
if name == 'random':
|
||||||
return self.random_lookup(valid_types=valid_types)
|
return self.random_lookup(valid_types=merged_valid_types)
|
||||||
|
|
||||||
# Do different things depending what the query looks like
|
# Do different things depending what the query looks like
|
||||||
# Note: Term objects do an exact match, so we don't have to worry about
|
# Note: Term objects do an exact match, so we don't have to worry about
|
||||||
|
@ -347,16 +398,8 @@ class PokedexLookup(object):
|
||||||
# Not an integer
|
# Not an integer
|
||||||
query = whoosh.query.Term(u'name', name)
|
query = whoosh.query.Term(u'name', name)
|
||||||
|
|
||||||
### Filter by type of object
|
if type_term:
|
||||||
type_terms = []
|
query = query & type_term
|
||||||
for valid_type in valid_types:
|
|
||||||
table_name = self._parse_table_name(valid_type)
|
|
||||||
if table_name:
|
|
||||||
# Quietly ignore bogus valid_types; more likely to DTRT
|
|
||||||
type_terms.append(whoosh.query.Term(u'table', table_name))
|
|
||||||
|
|
||||||
if type_terms:
|
|
||||||
query = query & whoosh.query.Or(type_terms)
|
|
||||||
|
|
||||||
|
|
||||||
### Actual searching
|
### Actual searching
|
||||||
|
@ -426,15 +469,21 @@ class PokedexLookup(object):
|
||||||
|
|
||||||
return self.lookup(unicode(n), valid_types=[ partitions[0][0] ])
|
return self.lookup(unicode(n), valid_types=[ partitions[0][0] ])
|
||||||
|
|
||||||
def prefix_lookup(self, prefix):
|
def prefix_lookup(self, prefix, valid_types=[]):
|
||||||
"""Returns terms starting with the given exact prefix.
|
"""Returns terms starting with the given exact prefix.
|
||||||
|
|
||||||
No special magic is currently done with the name; type prefixes are not
|
Type prefixes are recognized, but no other name munging is done.
|
||||||
recognized.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# Pop off any type prefix and merge with valid_types
|
||||||
|
prefix, merged_valid_types, type_term = \
|
||||||
|
self._apply_valid_types(prefix, valid_types)
|
||||||
|
|
||||||
query = whoosh.query.Prefix(u'name', self.normalize_name(prefix))
|
query = whoosh.query.Prefix(u'name', self.normalize_name(prefix))
|
||||||
|
|
||||||
|
if type_term:
|
||||||
|
query = query & type_term
|
||||||
|
|
||||||
searcher = self.index.searcher()
|
searcher = self.index.searcher()
|
||||||
searcher.weighting = LanguageWeighting()
|
searcher.weighting = LanguageWeighting()
|
||||||
results = searcher.search(query) # XXX , limit=self.MAX_LOOKUP_RESULTS)
|
results = searcher.search(query) # XXX , limit=self.MAX_LOOKUP_RESULTS)
|
||||||
|
|
Loading…
Reference in a new issue