Exemple #1
0
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)
Exemple #2
0
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)
Exemple #3
0
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)
Exemple #4
0
    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)
Exemple #5
0
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)
Exemple #6
0
    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