1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- from django.utils.translation import ugettext_lazy as _
- class SearchException(Exception):
- def __init__(self, message=None, suggestion=None):
- self.message = message
- self.suggestion = suggestion
- def __unicode__(self):
- return self.message
- class SearchQuery(object):
- def __init__(self, raw_query=None):
- """
- Build search query object
- """
- if raw_query:
- self.parse_query(raw_query)
-
- def parse_query(self, raw_query):
- """
- Parse raw search query into dict of lists of words that should be found and cant be found in string
- """
- self.criteria = {'+': [], '-': []}
- for word in unicode(raw_query).split():
- # Trim word and skip it if its empty
- word = unicode(word).strip().lower()
- if len(word) == 0:
- pass
-
- # Find word mode
- mode = '+'
- if word[0] == '-':
- mode = '-'
- word = unicode(word[1:]).strip()
-
- # Strip extra crap
- word = ''.join(e for e in word if e.isalnum())
-
- # Slice word?
- if len(word) <= 3:
- raise SearchException(_("One or more search phrases are shorter than four characters."))
- if mode == '+':
- if len(word) == 5:
- word = word[0:-1]
- if len(word) == 6:
- word = word[0:-2]
- if len(word) > 6:
- word = word[0:-3]
- self.criteria[mode].append(word)
-
- # Complain that there are no positive matches
- if not self.criteria['+'] and not self.criteria['-']:
- raise SearchException(_("Search query is invalid."))
-
- def search(self, value):
- """
- See if value meets search criteria, return True for success and False otherwhise
- """
- try:
- value = unicode(value).strip().lower()
- # Search for only
- if self.criteria['+'] and not self.criteria['-']:
- return self.search_for(value)
- # Search against only
- if self.criteria['-'] and not self.criteria['+']:
- return self.search_against(value)
- # Search if contains for values but not against values
- return self.search_for(value) and not self.search_against(value)
- except AttributeError:
- raise SearchException(_("You have to define search query before you will be able to search."))
-
- def search_for(self, value):
- """
- See if value is required
- """
- for word in self.criteria['+']:
- if value.find(word) != -1:
- return True
- return False
-
- def search_against(self, value):
- """
- See if value is forbidden
- """
- for word in self.criteria['-']:
- if value.find(word) != -1:
- return True
- return False
|