+ 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)
+
+