def _build_filter_tree(form, prefix): """_build_filter_tree(form, prefix) -- returns (tree,total,errors) Builds the subtree rooted at the prefix from the form. tree -- filter tree structure total -- total number of criteria errors -- list of errors Returns (None,0,None) if there is no subtree rooted at the prefix. Raises a KeyError if the tree is malformed.""" try: kind = form[prefix] except KeyError: return None, 0, None if kind in ('or', 'and', 'nor', 'nand'): prefix += '_' subtrees, total, errors = [], 0, [] for i in itertools.count(): subprefix = prefix + str(i) subtree, subtotal, suberr = _build_filter_tree(form, subprefix) if subtree is None: break # There are no more subtrees. elif subtotal == 0: continue # Skip this empty subtree. subtrees.append(subtree) total += subtotal errors.extend(suberr) return ('sub', kind, subtrees), total, errors else: rule = form[prefix + '_r'] if kind in ('title', 'album', 'artist'): string = get_unicode(form, prefix + '_f0') # If the kind is blank, then ignore the criterion. if not string: return (), 0, () # Validate the rule. if rule not in ('in', 'notin', 'start', 'notstart', 'end', 'notend', 'is', 'notis'): raise KeyError('bad string rule: %r' % rule) return (kind, rule, string), 1, () elif kind in ('time', 'track', 'play_count'): errors = [] # Get f0 and, if needed, f1. try: if kind == 'time': f0 = parse_time(form[prefix + '_f0']) else: f0 = parse_integer(form[prefix + '_f0']) except ValueError, err: errors.append(str(err)) if rule in ('inside', 'outside'): try: if kind == 'time': f1 = parse_time(form[prefix + '_f1']) else: f1 = parse_integer(form[prefix + '_f1']) except ValueError, err: errors.append(str(err)) # Validate the rule. if errors: return (), 1, errors elif rule in ('inside', 'outside'): return (kind, rule, (f0, f1)), 1, () elif rule in ('is', 'notis', 'lte', 'gte'): return (kind, rule, f0), 1, () else: raise KeyError('bad integer rule: %r' % rule)
def _build_filter_tree(form, prefix): """_build_filter_tree(form, prefix) -- returns (tree,total,errors) Builds the subtree rooted at the prefix from the form. tree -- filter tree structure total -- total number of criteria errors -- list of errors Returns (None,0,None) if there is no subtree rooted at the prefix. Raises a KeyError if the tree is malformed.""" try: kind = form[prefix] except KeyError: return None, 0, None if kind in ('or','and','nor','nand'): prefix += '_' subtrees, total, errors = [], 0, [] for i in itertools.count(): subprefix = prefix + str(i) subtree, subtotal, suberr = _build_filter_tree(form, subprefix) if subtree is None: break # There are no more subtrees. elif subtotal == 0: continue # Skip this empty subtree. subtrees.append(subtree) total += subtotal errors.extend(suberr) return ('sub', kind, subtrees), total, errors else: rule = form[prefix+'_r'] if kind in ('title','album','artist'): string = get_unicode(form, prefix+'_f0') # If the kind is blank, then ignore the criterion. if not string: return (), 0, () # Validate the rule. if rule not in ('in','notin','start','notstart','end','notend', 'is','notis'): raise KeyError('bad string rule: %r' % rule) return (kind, rule, string), 1, () elif kind in ('time','track','play_count'): errors = [] # Get f0 and, if needed, f1. try: if kind == 'time': f0 = parse_time(form[prefix+'_f0']) else: f0 = parse_integer(form[prefix+'_f0']) except ValueError, err: errors.append(str(err)) if rule in ('inside','outside'): try: if kind == 'time': f1 = parse_time(form[prefix+'_f1']) else: f1 = parse_integer(form[prefix+'_f1']) except ValueError, err: errors.append(str(err)) # Validate the rule. if errors: return (), 1, errors elif rule in ('inside', 'outside'): return (kind, rule, (f0, f1)), 1, () elif rule in ('is','notis','lte','gte'): return (kind, rule, f0), 1, () else: raise KeyError('bad integer rule: %r' % rule) elif kind in ('date_added','last_played'): if rule in ('last','nolast'): # Validate the number. This is human provided, so give an # error string if it's bad. try: number = parse_integer(form[prefix+'_f0']) except ValueError, err: return (), 1, (str(err),) # Validate the unit. This is provided by the form, so raise # a KeyError if it's bad. unit = form[prefix+'_f1'] if unit not in ('hour','day','week','month','year'): raise KeyError('bad date unit: %r' % unit) return (kind, rule, (number, unit)), 1, () else: errors = [] # Get f0 and, if needed, f1. try: f0 = parse_date(form[prefix+'_f0']) except ValueError, err: errors.append(str(err)) if rule in ('inside','outside'): try: f1 = parse_date(form[prefix+'_f1']) except ValueError, err: errors.append(str(err)) # Validate the rule. if errors: return (), 1, errors elif rule in ('before','after'): return (kind, rule, f0), 1, () elif rule in ('inside','outside'): return (kind, rule, (f0, f1)), 1, () else: raise KeyError('bad date rule: %r' % rule) else: raise KeyError('bad kind: %r' % kind)
except ValueError, err: errors.append(str(err)) # Validate the rule. if errors: return (), 1, errors elif rule in ('inside', 'outside'): return (kind, rule, (f0, f1)), 1, () elif rule in ('is', 'notis', 'lte', 'gte'): return (kind, rule, f0), 1, () else: raise KeyError('bad integer rule: %r' % rule) elif kind in ('date_added', 'last_played'): if rule in ('last', 'nolast'): # Validate the number. This is human provided, so give an # error string if it's bad. try: number = parse_integer(form[prefix + '_f0']) except ValueError, err: return (), 1, (str(err), ) # Validate the unit. This is provided by the form, so raise # a KeyError if it's bad. unit = form[prefix + '_f1'] if unit not in ('hour', 'day', 'week', 'month', 'year'): raise KeyError('bad date unit: %r' % unit) return (kind, rule, (number, unit)), 1, () else: errors = [] # Get f0 and, if needed, f1. try: f0 = parse_date(form[prefix + '_f0']) except ValueError, err: errors.append(str(err))