def run_format_func(funcname, arguments, m_audio, s_audio=None, extra=None, state=None): '''Runs the function function using the arguments specified from pudlestuff.function. Arguments: funcname -- String with the function name. Looked up using the dictionary pudlestuff.function.functions arguments -- List of arguments to pass to the function. Patterns should not be evaluated. They'll be evaluated here. m_audio -- Audio file containg multiple multiple values per key. Eg. {'artist': [u'Artist1': 'Artist2']} Keyword Arguments s_audio -- Same as m_audio, but containing strings as values. Generated on each run unless also passed. extra -- Dictionary containing extra fields that are to be used when matching fields. state -- Dictionary that hold state. Like {'__count': 15}. Used by some functions in puddlestuff.functions ''' #Get function try: if isinstance(funcname, basestring): func = functions[funcname] else: func = funcname except KeyError: raise ParseError( SYNTAX_ERROR.arg(funcname).arg( translate('Defaults', 'function does not exist.'))) extra = {} if extra is None else extra s_audio = stringtags(m_audio) if s_audio is None else s_audio reserved = {'tags': s_audio, 'm_tags': m_audio, 'state': state} dicts = [s_audio, extra, state] topass = get_function_arguments(funcname, func, arguments, reserved, True, *dicts) try: ret = func(**topass) if ret is None: return u'' return ret except TypeError, e: message = SYNTAX_ERROR.arg(funcname) message = message.arg(arglen_error(e, topass, func, False)) raise ParseError(message)
def run_format_func(funcname, arguments, m_audio, s_audio=None, extra=None, state=None): '''Runs the function function using the arguments specified from pudlestuff.function. Arguments: funcname -- String with the function name. Looked up using the dictionary pudlestuff.function.functions arguments -- List of arguments to pass to the function. Patterns should not be evaluated. They'll be evaluated here. m_audio -- Audio file containg multiple multiple values per key. Eg. {'artist': [u'Artist1': 'Artist2']} Keyword Arguments s_audio -- Same as m_audio, but containing strings as values. Generated on each run unless also passed. extra -- Dictionary containing extra fields that are to be used when matching fields. state -- Dictionary that hold state. Like {'__count': 15}. Used by some functions in puddlestuff.functions ''' #Get function try: if isinstance(funcname, basestring): func = functions[funcname] else: func = funcname except KeyError: raise ParseError(SYNTAX_ERROR.arg(funcname).arg( translate('Defaults', 'function does not exist.'))) extra = {} if extra is None else extra s_audio = stringtags(m_audio) if s_audio is None else s_audio reserved = {'tags': s_audio, 'm_tags': m_audio, 'state': state} dicts = [s_audio, extra, state] topass = get_function_arguments(funcname, func, arguments, reserved, True, *dicts) try: ret = func(**topass) if ret is None: return u'' return ret except TypeError, e: message = SYNTAX_ERROR.arg(funcname) message = message.arg(arglen_error(e, topass, func, False)) raise ParseError(message)
def parsefunc(s, m_audio, s_audio=None, state=None, extra=None, ret_i=False, path_sep=None): """Parses format strings. Returns the parsed string. Arguments --------- s -- *Unicode* format string. Eg. $replace(%artist%, name, surname) m_audio -- Audio file containg multiple multiple values per key. Eg. {'artist': [u'Artist1': 'Artist2']} Keyword Arguments s_audio -- Same as m_audio, but containing strings as values. Generated on each run unless also passed. extra -- Dictionary containing extra fields that are to be used when matching fields. state -- Dictionary that hold state. Like {'__count': 15}. Used by some functions in puddlestuff.functions >>> audio = {'artist': [u'Artist1'], 'track':u'10'} >>> parsefunc(u'%track% - %artist%', audio) Artist1 - 10 >>> state = {'__count': u'5'} >>> parsefunc(u'$num(%track%, 2)/$num(%__count%, 2). %artist%', audio, ... state = state) u'05/05. Artist1' """ #Yes I know this is a big ass function...but it works and I can't #see a way to split it without making it complicated. tokens = [] token = [] #List containing a function with it's arguments #Will look like ['replace', arg1, arg2, arg3] #functions get evaluated as soon as closing bracket found. func = [] #Flag determining if current within a function. Used for making comma's #significant in_func = False in_quote = False #field_open == -1 if not current in the middle of processing a field #eg. %artist%. Otherwise contains the index in s that the field started. field_open = -1 #Determine if next char should be escaped. escape = False s_audio = stringtags(m_audio) if s_audio is None else s_audio state = {} if state is None else state tags = s_audio.copy() tags.update(state) tags.update(extra if extra is not None else {}) escape_chars = set('()$%\\,') br_error = translate('Errors', 'No closing bracket found.') paths = [] i = 0 while 1: try: c = s[i] except IndexError: # Parsing's done. if in_func: raise ParseError(SYNTAX_ERROR.arg(func[0]).arg(br_error)) if token: tokens.append(replacevars(u''.join(token), tags)) break if c == u'"' and not escape: if in_func: token.append(c) in_quote = not in_quote elif c == u'"' and escape and in_func: token.append(u'\\"') i += 1 escape = False continue elif escape: token.append(c) escape = False i += 1 continue elif in_quote: token.append(c) elif c == u'\\' and not escape: escape = True i += 1 try: next_char = s[i] except IndexError: next_char = None if not in_func or (next_char not in escape_chars): token.append(c) escape = False continue elif c == u'$' and not (escape or (field_open >= 0)): func_name = re.search(u'^\$(\w+)\(', s[i:]) if not func_name: token.append(c) i += 1 continue if in_func: func_parsed, offset = parsefunc(s[i:], m_audio, s_audio, state, extra, True) token.append(func_parsed) i += offset + 1 continue tokens.append(replacevars(u''.join(token), tags)) token = [] func = [] func_name = func_name.groups(0)[0] func.append(func_name) in_func = True i += len(func_name) + 1 elif in_func and not in_quote and not token and c in whitespace: 'just increment counter' elif c == u',' and in_func and not in_quote: func.append(u''.join(token)) token = [] elif c == u')' and in_func: in_func = False if token or s[i - 1] == u',': func.append(u''.join(token)) func_parsed = run_format_func(func[0], func[1:], m_audio, s_audio, state=state, extra=extra) if ret_i: return func_parsed, i tokens.append(func_parsed) token = [] else: token.append(c) if path_sep and c == path_sep and not in_func: paths.append( len(u''.join(tokens) + replacevars(u''.join(token), tags)) - 1) escape = False i += 1 if path_sep and not ret_i: return paths, u''.join(tokens) else: return u''.join(tokens)
reserved = {'tags': s_audio, 'm_tags': m_audio, 'state': state} dicts = [s_audio, extra, state] topass = get_function_arguments(funcname, func, arguments, reserved, True, *dicts) try: ret = func(**topass) if ret is None: return u'' return ret except TypeError, e: message = SYNTAX_ERROR.arg(funcname) message = message.arg(arglen_error(e, topass, func, False)) raise ParseError(message) except FuncError, e: message = SYNTAX_ERROR.arg(funcname).arg(e.message) raise ParseError(message) def parsefunc(s, m_audio, s_audio=None, state=None, extra=None, ret_i=False, path_sep=None): """Parses format strings. Returns the parsed string. Arguments --------- s -- *Unicode* format string. Eg. $replace(%artist%, name, surname)
def parsefunc(s, m_audio, s_audio=None, state=None, extra=None, ret_i=False, path_sep=None): """Parses format strings. Returns the parsed string. Arguments --------- s -- *Unicode* format string. Eg. $replace(%artist%, name, surname) m_audio -- Audio file containg multiple multiple values per key. Eg. {'artist': [u'Artist1': 'Artist2']} Keyword Arguments s_audio -- Same as m_audio, but containing strings as values. Generated on each run unless also passed. extra -- Dictionary containing extra fields that are to be used when matching fields. state -- Dictionary that hold state. Like {'__count': 15}. Used by some functions in puddlestuff.functions >>> audio = {'artist': [u'Artist1'], 'track':u'10'} >>> parsefunc(u'%track% - %artist%', audio) Artist1 - 10 >>> state = {'__count': u'5'} >>> parsefunc(u'$num(%track%, 2)/$num(%__count%, 2). %artist%', audio, ... state = state) u'05/05. Artist1' """ #Yes I know this is a big ass function...but it works and I can't #see a way to split it without making it complicated. tokens = [] token = [] #List containing a function with it's arguments #Will look like ['replace', arg1, arg2, arg3] #functions get evaluated as soon as closing bracket found. func = [] #Flag determining if current within a function. Used for making comma's #significant in_func = False in_quote = False #field_open == -1 if not current in the middle of processing a field #eg. %artist%. Otherwise contains the index in s that the field started. field_open = -1 #Determine if next char should be escaped. escape = False s_audio = stringtags(m_audio) if s_audio is None else s_audio state = {} if state is None else state tags = s_audio.copy() tags.update(state) tags.update(extra if extra is not None else {}) escape_chars = set('()$%\\,') br_error = translate('Errors', 'No closing bracket found.') paths = [] i = 0 while 1: try: c = s[i] except IndexError: # Parsing's done. if in_func: raise ParseError(SYNTAX_ERROR.arg(func[0]).arg(br_error)) if token: tokens.append(replacevars(u''.join(token), tags)) break if c == u'"' and not escape: if in_func: token.append(c) in_quote = not in_quote elif c == u'"' and escape and in_func: token.append(u'\\"') i += 1 escape = False continue elif escape: token.append(c) escape = False i += 1 continue elif in_quote: token.append(c) elif c == u'\\' and not escape: escape = True i += 1 try: next_char = s[i] except IndexError: next_char = None if not in_func or (next_char not in escape_chars): token.append(c) escape = False continue elif c == u'$' and not (escape or (field_open >= 0)): func_name = re.search(u'^\$(\w+)\(', s[i:]) if not func_name: token.append(c) i += 1 continue if in_func: func_parsed, offset = parsefunc(s[i:], m_audio, s_audio, state, extra, True) token.append(func_parsed) i += offset + 1 continue tokens.append(replacevars(u''.join(token), tags)) token = [] func = [] func_name = func_name.groups(0)[0] func.append(func_name) in_func = True i += len(func_name) + 1 elif in_func and not in_quote and not token and c in whitespace: 'just increment counter' elif c == u',' and in_func and not in_quote: func.append(u''.join(token)) token = [] elif c == u')' and in_func: in_func = False if token or s[i-1] == u',': func.append(u''.join(token)) func_parsed = run_format_func(func[0], func[1:], m_audio, s_audio) if ret_i: return func_parsed, i tokens.append(func_parsed) token = [] else: token.append(c) if path_sep and c == path_sep and not in_func: paths.append(len(u''.join(tokens) + replacevars(u''.join(token), tags)) - 1) escape = False i += 1 if path_sep and not ret_i: return paths, u''.join(tokens) else: return u''.join(tokens)
reserved = {'tags': s_audio, 'm_tags': m_audio, 'state': state} dicts = [s_audio, extra, state] topass = get_function_arguments(funcname, func, arguments, reserved, True, *dicts) try: ret = func(**topass) if ret is None: return u'' return ret except TypeError, e: message = SYNTAX_ERROR.arg(funcname) message = message.arg(arglen_error(e, topass, func, False)) raise ParseError(message) except FuncError, e: message = SYNTAX_ERROR.arg(funcname).arg(e.message) raise ParseError(message) def parsefunc(s, m_audio, s_audio=None, state=None, extra=None, ret_i=False, path_sep=None): """Parses format strings. Returns the parsed string. Arguments --------- s -- *Unicode* format string. Eg. $replace(%artist%, name, surname) m_audio -- Audio file containg multiple multiple values per key. Eg. {'artist': [u'Artist1': 'Artist2']} Keyword Arguments s_audio -- Same as m_audio, but containing strings as values. Generated on each run unless also passed. extra -- Dictionary containing extra fields that are to be used