コード例 #1
0
ファイル: parser.py プロジェクト: nhrx/mpdc
def p_expression_filter(p):
    'expression : FILTER'
    exact = True if p[1][0].isupper() else False
    alias = (p[1][0] if p[1][1] in '"\'' else p[1][0:2]).lower()
    name = filters_alias.get(alias, '')
    pattern = p[1][2:-1] if p[1][1] in '"\'' else p[1][3:-1]
    if not name:
        warning('Filter [{}] does not exist'.format(alias))
        sys.exit(0)
    if name == 'lastfm_a':
        p[0] = OrderedSet()
        if exact:
            artists = lastfm.find_artists(pattern)
        else:
            artists = lastfm.search_artists(pattern)
        for artist in artists:
            p[0] |= mpd.find('artist', artist)
    elif name == 'lastfm_b':
        p[0] = OrderedSet()
        if exact:
            albums = lastfm.find_albums(pattern)
        else:
            albums = lastfm.search_albums(pattern)
        for album, artist in albums:
            matched_songs = mpd.find_multiple(albumartist=artist, album=album)
            if not matched_songs:
                matched_songs = mpd.find_multiple(artist=artist, album=album)
            p[0] |= matched_songs
        p[0] = mpd.set_sort(p[0])
    elif exact:
        p[0] = OrderedSet(mpd.find(name, pattern))
    else:
        p[0] = OrderedSet(mpd.search(name, pattern))
コード例 #2
0
ファイル: parser.py プロジェクト: nhrx/mpdc
def p_expression_collection(p):
    'expression : COLLECTION'
    p[0] = OrderedSet()
    if p[1] in collectionsmanager.c:
        collection = collectionsmanager.c[p[1]]
        if 'expression' in collection:
            p[0] |= parser.parse(collection['expression'],
                    lexer=lex.lex(debug=0, reflags=re.UNICODE|re.IGNORECASE))
        if 'songs' in collection:
            p[0] |= OrderedSet(collection['songs'])
        if enable_command and 'command' in collection:
            try:
                output = subprocess.check_output(collection['command'],
                                                 shell=True)
                p[0] |= OrderedSet(format_mpc_output(output.decode()))
            except subprocess.CalledProcessError:
                warning('Error while executing `command` in collection [{}]'.
                        format(p[1]))
                sys.exit(0)
        if 'sort' in collection:
            p[0] = mpd.set_sort(p[0])
    elif p[1] == 'all':
        p[0] = OrderedSet(mpd.get_all_songs())
    elif p[1] == 'c':
        p[0] = OrderedSet(mpd.get_playlist_songs())
    elif p[1] == 'C':
        c_song = mpd.get_current_song()
        if c_song is not None:
            p[0] = OrderedSet([c_song])
    elif p[1] == 'A':
        c_song = mpd.get_current_song()
        if c_song is not None:
            p[0] = OrderedSet(mpd.find('artist',
                                       mpd.get_tag(c_song, 'artist')))
    elif p[1] == 'B':
        c_song = mpd.get_current_song()
        if c_song is not None:
            p[0] = OrderedSet(mpd.find_multiple(
                              albumartist=mpd.get_tag(c_song, 'albumartist'),
                              album=mpd.get_tag(c_song, 'album')))
            if not p[0]:
                p[0] = OrderedSet(mpd.find_multiple(
                                  artist=mpd.get_tag(c_song, 'artist'),
                                  album=mpd.get_tag(c_song, 'album')))
    else:
        warning('Collection [{}] does not exist'.format(p[1]))
        sys.exit(0)
コード例 #3
0
ファイル: parser.py プロジェクト: madjar/mpdc
def p_expression_collection(p):
    'expression : COLLECTION'
    if p[1] in collections:
        collection = collections[p[1]]
        p[0] = OrderedSet()
        if 'expression' in collection:
            p[0] |= p.parser.parse(collection['expression'],
                                   lexer=lex.lex(debug=0, reflags=re.UNICODE))
        if 'songs' in collection:
            p[0] |= OrderedSet(collection['songs'])
        if enable_command and 'command' in collection:
            try:
                output = check_output(collection['command'], shell=True)
                p[0] |= OrderedSet(format_mpc_output(output.decode()))
            except CalledProcessError:
                warning('Error while executing `command` in collection [%s]' %
                        p[1])
                sys.exit(0)
        if 'sort' in collection:
            p[0] = mpd.set_sort(p[0])

    elif p[1] == 'all':
        p[0] = OrderedSet(mpd.get_all_songs())
    elif p[1] == 'c':
        p[0] = OrderedSet(mpd.get_playlist_songs())
    elif p[1] == 'C':
        p[0] = OrderedSet([mpd.get_current_song()])
    elif p[1] == 'A':
        c_song = mpd.get_current_song()
        p[0] = OrderedSet(mpd.find('artist', mpd.get_tag(c_song, 'artist')))
    elif p[1] == 'B':
        c_song = mpd.get_current_song()
        p[0] = OrderedSet(mpd.find_multiple(
                                        artist=mpd.get_tag(c_song, 'artist'),
                                        album=mpd.get_tag(c_song, 'album')))
    else:
        warning('Collection [%s] doesn\'t exist' % p[1])
        sys.exit(0)
コード例 #4
0
ファイル: parser.py プロジェクト: madjar/mpdc
def p_expression_modifier(p):
    'expression : expression MODIFIER'
    modifier = (p[2][1:]).lstrip()

    # Sorting modifier
    if modifier == 's':
        p[0] = mpd.set_sort(p[1])

    # N-random songs modifier
    elif re.match(r'^r[0-9]+$', modifier):
        try:
            p[0] = OrderedSet(random.sample(p[1], int(modifier[1:])))
        except ValueError:
            p[0] = p[1]

    # N-random artists modifier
    elif re.match(r'^ra[0-9]+$', modifier):
        artists = OrderedSet()
        for song in p[1]:
            artists.add(mpd.get_tag(song, 'artist'))
        try:
            r_artists = OrderedSet(random.sample(artists, int(modifier[2:])))
        except ValueError:
            p[0] = p[1]
        else:
            songs = []
            for artist in r_artists:
                songs.extend(mpd.find('artist', artist))
            p[0] = OrderedSet([song for song in p[1] if song in songs])

    # N-random albums modifier
    elif re.match(r'^rb[0-9]+$', modifier):
        albums = OrderedSet()
        for song in p[1]:
            albums.add(mpd.get_tags(song, ('album', 'artist')))
        try:
            r_albums = OrderedSet(random.sample(albums, int(modifier[2:])))
        except ValueError:
            p[0] = p[1]
        else:
            songs = []
            for album, artist in r_albums:
                songs.extend(mpd.find_multiple(album=album, artist=artist))
            p[0] = OrderedSet([song for song in p[1] if song in songs])

    # N-minutes-long modifier
    elif re.match(r'^d[0-9]+$', modifier):
        total_duration = int(modifier[1:]) * 60
        d = 0
        p[0] = OrderedSet()
        p[1] = list(p[1])
        random.shuffle(p[1])
        for song in p[1]:
            if d < total_duration:
                p[0].add(song)
                d += int(mpd.get_tag(song, 'time'))
            else:
                break

    # N-similar artists modifier
    elif re.match(r'^i?sa[0-9]+$', modifier):
        include = True if modifier[0] == 'i' else False
        limit = int((modifier[3:] if include else modifier[2:]))
        w_tags = defaultdict(int)
        for song in p[1]:
            tags = lastfm.get_artist_tags(mpd.get_tag(song, 'artist'))
            for tag in tags:
                w_tags[tag] += tags[tag]
        if not w_tags:
            p[0] = p[1] if include else OrderedSet()
        else:
            songs = []
            similar_artists = lastfm.get_similar_artists(w_tags)
            for artist, score in similar_artists:
                if not limit:
                    break
                matched_songs = mpd.find('artist', artist)
                if not include:
                    matched_songs = OrderedSet(matched_songs) - p[1]
                if matched_songs:
                    songs.extend(matched_songs)
                    limit -= 1
            p[0] = OrderedSet(songs)

    # N-similar albums modifier
    elif re.match(r'^i?sb[0-9]+$', modifier):
        include = True if modifier[0] == 'i' else False
        limit = int((modifier[3:] if include else modifier[2:]))
        w_tags = defaultdict(int)
        for song in p[1]:
            tags = lastfm.get_album_tags(mpd.get_tag(song, 'album'),
                                         mpd.get_tag(song, 'artist'))
            for tag in tags:
                w_tags[tag] += tags[tag]
        if not w_tags:
            p[0] = p[1] if include else OrderedSet()
        else:
            songs = []
            for (album, artist), score in lastfm.get_similar_albums(w_tags):
                if not limit:
                    break
                matched_songs = mpd.find_multiple(album=album, artist=artist)
                if not include:
                    matched_songs = OrderedSet(matched_songs) - p[1]
                if matched_songs:
                    songs.extend(matched_songs)
                    limit -= 1
            p[0] = OrderedSet(songs)

    else:
        warning('Modifier [%s] doesn\'t exist' % modifier)
        sys.exit(0)
コード例 #5
0
ファイル: parser.py プロジェクト: nhrx/mpdc
def p_expression_modifier(p):
    'expression : expression MODIFIER'
    modifier = (p[2][1:]).lstrip()

    # Sorting modifier
    if modifier == 's':
        p[0] = mpd.set_sort(p[1])

    # N-random songs modifier
    elif re.match(r'^r[0-9]+$', modifier):
        p[1] = exclude_songs(p[1])
        try:
            p[0] = OrderedSet(random.sample(p[1], int(modifier[1:])))
        except ValueError:
            p[0] = p[1]

    # N-random artists modifier
    elif re.match(r'^ra[0-9]+$', modifier):
        p[1] = exclude_songs(p[1])
        artists = OrderedSet()
        for song in p[1]:
            artists.add(mpd.get_tag(song, 'artist'))
        try:
            r_artists = OrderedSet(random.sample(artists, int(modifier[2:])))
        except ValueError:
            p[0] = p[1]
        else:
            songs = []
            for artist in r_artists:
                songs.extend(mpd.find('artist', artist))
            p[0] = OrderedSet([song for song in p[1] if song in songs])

    # N-random albums modifier
    elif re.match(r'^rb[0-9]+$', modifier):
        p[1] = exclude_songs(p[1])
        albums = OrderedSet()
        for song in p[1]:
            albums.add(mpd.get_tags(song, ('album', 'albumartist')))
        try:
            r_albums = OrderedSet(random.sample(albums, int(modifier[2:])))
        except ValueError:
            p[0] = p[1]
        else:
            songs = []
            for album, artist in r_albums:
                matched_songs = mpd.find_multiple(album=album,
                                                  albumartist=artist)
                if not matched_songs:
                    matched_songs = mpd.find_multiple(album=album,
                                                      artist=artist)
                songs.extend(matched_songs)
            p[0] = OrderedSet([song for song in p[1] if song in songs])

    # N-minutes-long modifier
    elif re.match(r'^d[0-9]+$', modifier):
        p[1] = exclude_songs(p[1])
        total_duration = int(modifier[1:]) * 60
        d = 0
        p[0] = OrderedSet()
        p[1] = list(p[1])
        random.shuffle(p[1])
        for song in p[1]:
            if d < total_duration:
                p[0].add(song)
                d += int(mpd.get_tag(song, 'time'))
            else:
                break

    # N-similar artists modifier
    elif re.match(r'^i?sa[0-9]+$', modifier):
        include = True if modifier[0] == 'i' else False
        limit = int(modifier[3:] if include else modifier[2:])
        w_tags = collections.defaultdict(int)
        for song in p[1]:
            tags = lastfm.get_artist_tags(mpd.get_tag(song, 'artist'))
            for tag, w in tags.items():
                w_tags[tag] += w
        if not w_tags:
            p[0] = p[1] if include else OrderedSet()
        else:
            songs = []
            for artist, _ in lastfm.get_similar_artists(w_tags):
                if not limit:
                    break
                matched_songs = mpd.find('artist', artist)
                if not include:
                    matched_songs = OrderedSet(matched_songs) - p[1]
                if matched_songs:
                    songs.extend(matched_songs)
                    limit -= 1
            p[0] = OrderedSet(songs)

    # N-similar albums modifier
    elif re.match(r'^i?sb[0-9]+$', modifier):
        include = True if modifier[0] == 'i' else False
        limit = int(modifier[3:] if include else modifier[2:])
        w_tags = collections.defaultdict(int)
        for song in p[1]:
            tags = lastfm.get_album_tags(mpd.get_tag(song, 'album'),
                                         mpd.get_tag(song, 'albumartist'))
            for tag, w in tags.items():
                w_tags[tag] += w
        if not w_tags:
            p[0] = p[1] if include else OrderedSet()
        else:
            songs = []
            for (album, artist), score in lastfm.get_similar_albums(w_tags):
                if not limit:
                    break
                matched_songs = mpd.find_multiple(album=album,
                                                  albumartist=artist)
                if not matched_songs:
                    matched_songs = mpd.find_multiple(album=album,
                                                      artist=artist)
                if not include:
                    matched_songs = OrderedSet(matched_songs) - p[1]
                if matched_songs:
                    songs.extend(matched_songs)
                    limit -= 1
            p[0] = OrderedSet(songs)

    # N-top tracks modifier
    elif re.match(r'^p[0-9]+$', modifier):
        p[0] = OrderedSet()
        artists = OrderedSet(mpd.get_tag(song, 'artist') for song in p[1])
        for artist in artists:
            limit = int(modifier[1:])
            for track in lastfm.get_artist_top_tracks(artist):
                if not limit:
                    break
                matched_songs = mpd.search_multiple(artist=artist, title=track)
                if len(matched_songs) > 1:
                    matched_songs = mpd.find_multiple(artist=artist, title=track) \
                                    or matched_songs
                if matched_songs:
                    p[0].add(matched_songs[0])
                    limit -= 1

    else:
        warning('Modifier [{}] does not exist'.format(modifier))
        sys.exit(0)