Fix tag expression bugs, move work to searchhelpers
Fix handling of bad tags, bad syntax, empty expression. Remove unnecessary warning_bag from matcher builder
This commit is contained in:
		
							parent
							
								
									884b1a1aa5
								
							
						
					
					
						commit
						241d1466eb
					
				
					 2 changed files with 56 additions and 21 deletions
				
			
		|  | @ -768,24 +768,17 @@ class PDBPhotoMixin: | ||||||
|                 self._cached_frozen_children = frozen_children |                 self._cached_frozen_children = frozen_children | ||||||
| 
 | 
 | ||||||
|         if tag_expression: |         if tag_expression: | ||||||
|             expression_tree = expressionmatch.ExpressionTree.parse(tag_expression) |             tag_expression_tree = searchhelpers.tag_expression_tree_builder( | ||||||
|             expression_tree.map(self.normalize_tagname) |                 tag_expression=tag_expression, | ||||||
|             expression_matcher = searchhelpers.tag_expression_matcher_builder( |                 photodb=self, | ||||||
|                 frozen_children, |                 frozen_children=frozen_children, | ||||||
|                 warning_bag=warning_bag, |                 warning_bag=warning_bag, | ||||||
|             ) |             ) | ||||||
|             for node in expression_tree.walk_leaves(): |             if tag_expression_tree is None: | ||||||
|                 if node.token in frozen_children: |                 tag_expression = None | ||||||
|                     continue |             else: | ||||||
| 
 |                 print(tag_expression_tree) | ||||||
|                 exc = exceptions.NoSuchTag(node.token) |                 tag_match_function = searchhelpers.tag_expression_matcher_builder(frozen_children) | ||||||
|                 if warning_bag is not None: |  | ||||||
|                     warning_bag.add(exc.error_message) |  | ||||||
|                     node.token = None |  | ||||||
|                 else: |  | ||||||
|                     raise exc |  | ||||||
| 
 |  | ||||||
|             expression_tree.prune() |  | ||||||
| 
 | 
 | ||||||
|         if filename: |         if filename: | ||||||
|             filename_tree = expressionmatch.ExpressionTree.parse(filename) |             filename_tree = expressionmatch.ExpressionTree.parse(filename) | ||||||
|  | @ -859,9 +852,9 @@ class PDBPhotoMixin: | ||||||
|                     continue |                     continue | ||||||
| 
 | 
 | ||||||
|                 if tag_expression: |                 if tag_expression: | ||||||
|                     success = expression_tree.evaluate( |                     success = tag_expression_tree.evaluate( | ||||||
|                         photo_tags, |                         photo_tags, | ||||||
|                         match_function=expression_matcher, |                         match_function=tag_match_function, | ||||||
|                     ) |                     ) | ||||||
|                     if not success: |                     if not success: | ||||||
|                         #print('Failed tag expression') |                         #print('Failed tag expression') | ||||||
|  |  | ||||||
|  | @ -3,6 +3,8 @@ from . import exceptions | ||||||
| from . import helpers | from . import helpers | ||||||
| from . import objects | from . import objects | ||||||
| 
 | 
 | ||||||
|  | from voussoirkit import expressionmatch | ||||||
|  | 
 | ||||||
| def build_query(orderby, notnulls): | def build_query(orderby, notnulls): | ||||||
|     query = 'SELECT * FROM photos' |     query = 'SELECT * FROM photos' | ||||||
| 
 | 
 | ||||||
|  | @ -330,8 +332,48 @@ def normalize_tag_mmf(tags, photodb, warning_bag=None): | ||||||
| 
 | 
 | ||||||
|     return tagset |     return tagset | ||||||
| 
 | 
 | ||||||
| def tag_expression_matcher_builder(frozen_children, warning_bag=None): | def tag_expression_tree_builder( | ||||||
|     def matcher(photo_tags, tagname): |         tag_expression, | ||||||
|  |         photodb, | ||||||
|  |         frozen_children, | ||||||
|  |         warning_bag=None | ||||||
|  |     ): | ||||||
|  |     try: | ||||||
|  |         expression_tree = expressionmatch.ExpressionTree.parse(tag_expression) | ||||||
|  |     except expressionmatch.NoTokens: | ||||||
|  |         return None | ||||||
|  |     except Exception as exc: | ||||||
|  |         warning_bag.add('Bad expression "%s"' % tag_expression) | ||||||
|  |         return None | ||||||
|  | 
 | ||||||
|  |     for node in expression_tree.walk_leaves(): | ||||||
|  |         try: | ||||||
|  |             node.token = photodb.normalize_tagname(node.token) | ||||||
|  |         except (exceptions.TagTooShort, exceptions.TagTooLong) as exc: | ||||||
|  |             if warning_bag is not None: | ||||||
|  |                 warning_bag.add(exc.error_message) | ||||||
|  |                 node.token = None | ||||||
|  |             else: | ||||||
|  |                 raise | ||||||
|  | 
 | ||||||
|  |         if node.token is None: | ||||||
|  |             continue | ||||||
|  | 
 | ||||||
|  |         if node.token not in frozen_children: | ||||||
|  |             exc = exceptions.NoSuchTag(node.token) | ||||||
|  |             if warning_bag is not None: | ||||||
|  |                 warning_bag.add(exc.error_message) | ||||||
|  |                 node.token = None | ||||||
|  |             else: | ||||||
|  |                 raise exc | ||||||
|  | 
 | ||||||
|  |     expression_tree.prune() | ||||||
|  |     if expression_tree.token is None: | ||||||
|  |         return None | ||||||
|  |     return expression_tree | ||||||
|  | 
 | ||||||
|  | def tag_expression_matcher_builder(frozen_children): | ||||||
|  |     def match_function(photo_tags, tagname): | ||||||
|         ''' |         ''' | ||||||
|         Used as the `match_function` for the ExpressionTree evaluation. |         Used as the `match_function` for the ExpressionTree evaluation. | ||||||
| 
 | 
 | ||||||
|  | @ -346,4 +388,4 @@ def tag_expression_matcher_builder(frozen_children, warning_bag=None): | ||||||
|         options = frozen_children[tagname] |         options = frozen_children[tagname] | ||||||
|         return any(option in photo_tags for option in options) |         return any(option in photo_tags for option in options) | ||||||
| 
 | 
 | ||||||
|     return matcher |     return match_function | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue