B/W: Footprints! Replace the old ones with a B/W rip.
[zzz-pokedex.git] / pokedex / lookup.py
index ca0e5b0..98e69c4 100644 (file)
@@ -69,10 +69,11 @@ class LanguageWeighting(whoosh.scoring.Weighting):
         # Apply extra weight
         weight = weight * self.extra_weights.get(text, 1.0)
 
-        if doc['language'] == None:
+        language = doc.get('language')
+        if language is None:
             # English (well, "default"); leave it at 1
             return weight
-        elif doc['language'] == u'Roomaji':
+        elif language == u'Roomaji':
             # Give Roomaji a little boost; it's most likely to be searched
             return weight * 0.9
         else:
@@ -175,7 +176,13 @@ class PokedexLookup(object):
             display_name=whoosh.fields.STORED,  # non-lowercased name
         )
 
-        if not os.path.exists(self.directory):
+        if os.path.exists(self.directory):
+            # create_in() isn't totally reliable, so just nuke whatever's there
+            # manually.  Try to be careful about this...
+            for f in os.listdir(self.directory):
+                if re.match('^_?(MAIN|SPELL)_', f):
+                    os.remove(os.path.join(self.directory, f))
+        else:
             os.mkdir(self.directory)
 
         self.index = whoosh.index.create_in(self.directory, schema=schema,
@@ -289,47 +296,53 @@ class PokedexLookup(object):
             name = name.strip()
 
             prefixes = prefix_chunk.split(',')
-            user_valid_types = [_.strip() for _ in prefixes]
+            user_valid_types = []
+            for prefix in prefixes:
+                prefix = prefix.strip()
+                if prefix:
+                    user_valid_types.append(prefix)
 
         # 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
+        # forbidden, completely ignore what the user requested.
+        # And, just to complicate matters: "type" and language need to be
+        # considered separately.
+        def merge_requirements(func):
+            user = filter(func, user_valid_types)
+            system = filter(func, valid_types)
+
+            if user and system:
+                merged = list(set(user) & set(system))
+                if merged:
+                    return merged
+                else:
+                    # No overlap; use the system restrictions
+                    return system
+            else:
+                # One or the other is blank; use the one that's not
+                return user or system
 
-        if not combined_valid_types:
-            # No restrictions
-            return name, [], None
+        # @foo means language must be foo; otherwise it's a table name
+        lang_requirements = merge_requirements(lambda req: req[0] == u'@')
+        type_requirements = merge_requirements(lambda req: req[0] != u'@')
+        all_requirements = lang_requirements + type_requirements
 
         # Construct the term
-        type_terms = []
         lang_terms = []
-        final_valid_types = []
-        for valid_type in combined_valid_types:
-            if valid_type.startswith(u'@'):
-                # @foo means: language must be foo.
-                # Allow for either country or language codes
-                lang_code = valid_type[1:]
-                lang_terms.append(whoosh.query.Term(u'iso639', lang_code))
-                lang_terms.append(whoosh.query.Term(u'iso3166', lang_code))
-            else:
-                # otherwise, this is a type/table name
-                table_name = self._parse_table_name(valid_type)
+        for lang in lang_requirements:
+            # Allow for either country or language codes
+            lang_code = lang[1:]
+            lang_terms.append(whoosh.query.Term(u'iso639', lang_code))
+            lang_terms.append(whoosh.query.Term(u'iso3166', lang_code))
 
-                # Quietly ignore bogus valid_types; more likely to DTRT
-                if table_name:
-                    type_terms.append(whoosh.query.Term(u'table', table_name))
+        type_terms = []
+        for type in type_requirements:
+            table_name = self._parse_table_name(type)
+
+            # Quietly ignore bogus valid_types; more likely to DTRT
+            if table_name:
+                type_terms.append(whoosh.query.Term(u'table', table_name))
 
         # Combine both kinds of restriction
         all_terms = []
@@ -338,7 +351,7 @@ class PokedexLookup(object):
         if lang_terms:
             all_terms.append(whoosh.query.Or(lang_terms))
 
-        return name, combined_valid_types, whoosh.query.And(all_terms)
+        return name, all_requirements, whoosh.query.And(all_terms)
 
 
     def _parse_table_name(self, name):
@@ -380,7 +393,7 @@ class PokedexLookup(object):
             results.append(LookupResult(object=obj,
                                         indexed_name=record['name'],
                                         name=record['display_name'],
-                                        language=record['language'],
+                                        language=record.get('language'),
                                         iso639=record['iso639'],
                                         iso3166=record['iso3166'],
                                         exact=exact))