Пример #1
0
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
def main():
    config = ConfigParser()

    config.add_section('mpd')
    config['mpd']['host'] = input('>> MPD host [localhost]: ') or 'localhost'
    config['mpd']['port'] = input('>> MPD port [6600]: ') or '6600'
    config['mpd']['password'] = input('>> MPD password []: ') or ''
    print('\n')

    config.add_section('mpdc')
    print('Later, you will propably need to store and edit your collections/'
          'playlists in a specific file. Please create an empty file '
          '(e.g. collections.mpdc) where you want and write its path below.')

    while True:
        path = input('>> Full path of the collections file: ')
        if not os.path.isfile(path):
            warning('Can\'t find the file: ' + path)
        else:
            break
    print('\n')
    config['mpdc']['collections'] = path

    colors = input('>> Enable colors [Y/n]: ').lower() or 'y'
    if colors == 'y':
        config['mpdc']['colors'] = 'red, green, blue'
    print('\n')

    filepath = os.path.expanduser('~/.mpdc')
    try:
        with open(filepath, 'w') as configfile:
            config.write(configfile)
            info('Writing configuration file in: ' + filepath)
    except IOError:
        warning('Can\'t write configuration file in: ' + filepath)
Пример #3
0
def check(args):
    songs = []
    song_tags_dict = mpd.get_all_songs_tags()
    for song in parser.parse(' '.join(args.collection)):
        tags = song_tags_dict[song]
        missing_tags = [tag for tag, value in tags.items() if not value]
        if missing_tags:
            warning(colorize(song, colors[0]))
            print('missing tag(s): ' + colorize(', '.join(missing_tags),
                                                colors[1 % len(colors)]))
        else:
            songs.append(tuple(sorted(tags.items())))
    duplicates = [dict(tags) for tags, nb in Counter(songs).items() if nb > 1]
    if duplicates:
        print('\nConflict(s) found:')
        print('------------------')
        for tags in duplicates:
            warning('Conflict with tags ' + colorize(repr_tags([tags['artist'],
                                                               tags['album'],
                                                               tags['title'],
                                                               tags['track']]),
                                                     colors[1 % len(colors)]))
            # necessary because MPDHelper's get_all_songs_tags falls back
            # to artist if albumartist is empty, while it's find_multiple
            # (mpdclient.find in fact) does not
            # not a solution really, so FIXME
            tags.pop('albumartist')
            files_matched = mpd.find_multiple(**tags)
            print('files matched:\n' + colorize('\n'.join(files_matched),
                                                colors[0]))
Пример #4
0
    def __init__(self):
        self.timeout = 0
        self.artists_tags = cache.read('lastfm_artists_tags')
        self.albums_tags = cache.read('lastfm_albums_tags')
        self.tracks_tags = cache.read('lastfm_tracks_tags')

        if not (self.artists_tags and self.albums_tags and self.tracks_tags):
            warning('You should update the LastFM database')
Пример #5
0
 def remove_songs(self, alias, songs_files):
     if alias in self.collections and 'songs' in self.collections[alias]:
         remaining_songs = [s for s in self.collections[alias]['songs']
                            if s not in songs_files]
         if 'mpd_playlist' in self.collections[alias]:
             mpd.clear_stored_playlist(alias)
             mpd.add_songs_stored_playlist(alias, remaining_songs)
         self.collections[alias]['songs'] = remaining_songs
         self.need_update = True
     else:
         warning('Collection [%s] doesn\'t exist or contains no song to '
                 'remove' % alias)
Пример #6
0
def change_default_profile(profile):
    config = ConfigParser()
    filepath = os.path.expanduser('~/.mpdc')
    if not config.read(filepath):
        warning('Cannot read the configuration file, run mpdc-configure')
        return
    config['profiles']['default'] = str(profile)
    try:
        with open(filepath, 'w') as configfile:
            config.write(configfile)
            info('Writing configuration file in: ' + filepath)
    except IOError:
        warning('Cannot write configuration file in: ' + filepath)
Пример #7
0
 def get_album_tags(self, album, artist, update=False):
     if not update:
         if not self.albums_tags:
             warning('You should update the LastFM database')
         elif (album, artist) in self.albums_tags:
             return self.albums_tags[(album, artist)]
         return {}
     else:
         data = self.request('album_tags', artist=artist, album=album)
         if data is not None:
             if 'tag' in data.get('toptags', {}):
                 return self.sanitize_tags(data['toptags']['tag'])
         return {}
Пример #8
0
 def get_similar_artists(self, query):
     if not self.artists_tags:
         warning('You should update the LastFM database')
         return
     scores = {}
     for artist, tags in self.artists_tags.items():
         if tags:
             score = similarity(tags, query)
             if score > LastfmHelper.min_similarity:
                 scores[artist] = score
     scores_desc = sorted(scores.items(), key=itemgetter(1), reverse=True)
     for artist in scores_desc:
         yield artist
Пример #9
0
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)
Пример #10
0
def show(args):
    if args.alias in collections:
        if 'mpd_playlist' in collections[args.alias]:
            info('This collection is stored as a MPD playlist\n')
        if 'sort' in collections[args.alias]:
            info('This collection is sorted automatically\n')
        if 'expression' in collections[args.alias]:
            print(collections[args.alias]['expression'])
        if 'command' in collections[args.alias]:
            print('command: ' + collections[args.alias]['command'])
            print('--------\n')
        if 'songs' in collections[args.alias]:
            print('songs:')
            print('------')
            display_songs(collections[args.alias]['songs'], args.m)
    else:
        warning('Stored collection [%s] doesn\'t exist' % args.alias)
Пример #11
0
def raw_to_optimized(collections_raw):
    collections = OrderedDict()
    alias = ''
    for line in collections_raw:
        if line.startswith('--'):
            alias = (line[2:] if line[2] not in '@#' else line[3:]).strip()
            collections[alias] = {}
            if line[2] == '@':
                collections[alias]['sort'] = True
            elif line[2] == '#':
                collections[alias]['special'] = True
        elif alias:
            if line.startswith('command:'):
                collections[alias]['command'] = line[8:].strip()
            elif line.startswith('songs:'):
                collections[alias]['songs'] = []
            elif line.strip():
                if ('songs' in collections[alias] and
                   (line.startswith('    ') or line.startswith('\t'))):
                    tags = ast.literal_eval('({})'.format(line.strip()))
                    artist, album, title, track = tags
                    matched_songs = mpd.find_multiple(artist=artist,
                                                      album=album,
                                                      title=title,
                                                      track=track)
                    if matched_songs:
                        collections[alias]['songs'].append(matched_songs[0])
                    else:
                        warning('In collection [{}], these tags do not match '
                                'any song: {}'.format(alias, repr_tags(tags)))
                else:
                    if 'expression' not in collections[alias]:
                        collections[alias]['expression'] = line
                    else:
                        collections[alias]['expression'] += line
    # add MPD native playlists
    for playlist in mpd.get_stored_playlists():
        if playlist not in collections:
            collections[playlist] = {'mpd_playlist': True,
                                     'songs':
                                       mpd.get_stored_playlist_songs(playlist)}
        else:
            warning('MPD playlist [{}] was ignored because a collection with '
                    'the same name already exists'.format(playlist))
    return collections
Пример #12
0
 def add_songs(self, alias, songs_files):
     if not alias in self.c or not 'mpd_playlist' in self.c[alias]:
         for song in songs_files[:]:
             if not all(mpd.get_tags(song)):
                 warning('[{}] was not added (missing tags)'.format(song))
                 songs_files.remove(song)
     if alias in self.c:
         if 'songs' in self.c[alias]:
             self.collections[alias]['songs'].extend(songs_files)
         else:
             self.collections[alias]['songs'] = songs_files
         if 'mpd_playlist' in self.c[alias]:
             mpd.add_songs_stored_playlist(alias, songs_files)
     else:
         info('Collection [{}] will be created'.format(alias))
         self.collections[alias] = {}
         self.collections[alias]['songs'] = songs_files
     self.need_update = True
Пример #13
0
 def add_songs(self, alias, songs_files):
     if (not alias in self.collections or
         not 'mpd_playlist' in self.collections[alias]):
         for song in songs_files[:]:
             if not all(mpd.get_tags(song)):
                 warning('File not added, missing tag(s): [%s]' % song)
                 songs_files.remove(song)
     if alias in self.collections:
         if 'songs' in self.collections[alias]:
             self.collections[alias]['songs'].extend(songs_files)
         else:
             self.collections[alias]['songs'] = songs_files
         if 'mpd_playlist' in self.collections[alias]:
             mpd.add_songs_stored_playlist(alias, songs_files)
     else:
         info('Collection [%s] will be created' % alias)
         self.collections[alias] = {}
         self.collections[alias]['songs'] = songs_files
     self.need_update = True
Пример #14
0
def show(args):
    if args.alias in collectionsmanager.c:
        collection = collectionsmanager.c[args.alias]
        if "mpd_playlist" in collection:
            info("This collection is stored as a MPD playlist\n")
        elif "sort" in collection:
            info("This collection is sorted automatically\n")
        elif "special" in collection:
            info("This is a special collection\n")
        if "expression" in collection:
            print(collection["expression"])
        if "command" in collection:
            print("command: " + collection["command"])
            print("--------\n")
        if "songs" in collection:
            print("songs:")
            print("------")
            display_songs(collection["songs"], args.f)
    else:
        warning("Stored collection [{}] does not exist".format(args.alias))
Пример #15
0
def show(args):
    if args.alias in collectionsmanager.c:
        collection = collectionsmanager.c[args.alias]
        if 'mpd_playlist' in collection:
            info('This collection is stored as a MPD playlist\n')
        elif 'sort' in collection:
            info('This collection is sorted automatically\n')
        elif 'special' in collection:
            info('This is a special collection\n')
        if 'expression' in collection:
            print(collection['expression'])
        if 'command' in collection:
            print('command: ' + collection['command'])
            print('--------\n')
        if 'songs' in collection:
            print('songs:')
            print('------')
            display_songs(collection['songs'], args.f)
    else:
        warning('Stored collection [{}] does not exist'.format(args.alias))
Пример #16
0
    def request(self, method, **args):
        while LastfmHelper.last_request + LastfmHelper.delay > datetime.now():
            sleep(0.1)

        args_ = {key: quote(value) for (key, value) in args.items()}
        url = LastfmHelper.url + LastfmHelper.methods[method].format(**args_)

        try:
            raw_json = urlopen(url, timeout=15).read()
        except (socket.timeout, URLError):
            if self.timeout == 3:
                warning('Can\'t send the request after 4 attempts')
                self.timeout = 0
                return None
            self.timeout += 1
            warning('Time out... attempt n°' + str(self.timeout + 1))
            return self.request(method, **args)
        else:
            LastfmHelper.last_request = datetime.now()
            response = json.loads(raw_json.decode('utf-8'))
            if 'error' in response:
                warning('LastFM error: {}'.format(response['message']))
                return None
            self.timeout = 0
            return response
Пример #17
0
    def request(self, method, **args):
        if self.last_request + self.delay > datetime.now():
            time_to_sleep = self.last_request + self.delay - datetime.now()
            time.sleep(time_to_sleep.total_seconds())

        args_ = {key: urllib.parse.quote(value) for key, value in args.items()}
        url = self.url + self.methods[method].format(**args_)

        try:
            raw_json = urllib.request.urlopen(url, timeout=15).read()
        except (socket.timeout, urllib.error.URLError):
            if self.timeout == 3:
                warning('Cannot send the request after 4 attempts')
                self.timeout = 0
                return None
            self.timeout += 1
            warning('Time out... attempt n°' + str(self.timeout + 1))
            return self.request(method, **args)
        else:
            self.last_request = datetime.now()
            response = json.loads(raw_json.decode('utf-8'))
            if 'error' in response:
                warning('LastFM error: {}'.format(response['message']))
                return None
            self.timeout = 0
            return response
Пример #18
0
def configure(args):
    if args.switch:
        change_default_profile(args.switch)
        return
    config = ConfigParser()
    config.add_section('profiles')
    config['profiles']['host[1]'] = input('>> MPD host [localhost]: ') or \
                                    'localhost'
    config['profiles']['port[1]'] = input('>> MPD port [6600]: ') or '6600'
    config['profiles']['password[1]'] = input('>> MPD password []: ') or ''
    print('\n')

    config.add_section('mpdc')
    print('Later, you will propably need to store and edit your collections/'
          'playlists in a specific file. Please create an empty file '
          '(e.g. collections.mpdc) where you want and write its path below.')

    while True:
        path = input('>> Full path of the collections file: ')
        if os.path.isfile(path):
            break
        warning('Cannot find the file: ' + path)
    print('\n')
    config['mpdc']['collections'] = path

    colors = input('>> Enable colors [Y/n]: ').lower() or 'y'
    if colors == 'y':
        config['mpdc']['colors'] = 'green, red, blue'
    print('\n')

    config['mpdc']['columns'] = 'artist, title, album'

    filepath = os.path.expanduser('~/.mpdc')
    try:
        with open(filepath, 'w') as configfile:
            config.write(configfile)
            info('Writing configuration file in: ' + filepath)
    except IOError:
        warning('Cannot write configuration file in: ' + filepath)
Пример #19
0
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)
Пример #20
0
def check(args):
    songs = []
    for song, tags in mpd.get_all_songs_tags().items():
        missing_tags = [tag for tag, value in tags.items() if not value]
        if missing_tags:
            warning('You should tag [%s]' % colorize(song, colors[0]))
            print('missing tag(s): %s' % colorize(', '.join(missing_tags),
                                                  colors[1]))
        else:
            songs.append(tuple(sorted(tags.items())))
    duplicates = [dict(tags) for tags, nb in Counter(songs).items() if nb > 1]
    if duplicates:
        print('\nConflict(s) found:')
        print('------------------')
        for tags in duplicates:
            warning('Conflict with tags ' + colorize(repr_tags([tags['artist'],
                                                               tags['album'],
                                                               tags['title'],
                                                               tags['track']]),
                                                    colors[1]))
            files_matched = mpd.find_multiple(**tags)
            print('files matched: \n%s\n' % colorize('\n'.join(files_matched),
                                                     colors[0]))
Пример #21
0
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)
Пример #22
0
def t_error(t):
    warning('Illegal character `{}`'.format(t.value[0]))
    sys.exit(0)
Пример #23
0
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)
Пример #24
0
def p_error(t):
    warning('Syntax error')
    sys.exit(0)
Пример #25
0
def t_error(t):
    warning('Illegal character `%s`' % t.value[0])
    sys.exit(0)
Пример #26
0
# coding: utf-8
import os
import sys
from configparser import ConfigParser

from mpdc.libs.utils import Cache, warning, colors_c, columns_w


config = ConfigParser()

if not config.read(os.path.expanduser('~/.mpdc')):
    warning('Cannot read the configuration file, please run mpdc-configure')
    sys.exit(0)

try:
    config['profiles']
    config['profiles']['host[1]']
    config['profiles']['port[1]']
    config['profiles']['password[1]']
    config['mpdc']['collections']
except KeyError:
    warning('Invalid configuration file')
    sys.exit(0)

profiles = {}
for key in config['profiles']:
    if key == 'default':
        continue
    num = int(''.join(filter(str.isdigit, key)))
    if num not in profiles:
        profiles[num] = {
Пример #27
0
# coding: utf-8
import os
import sys
from configparser import ConfigParser

from mpdc.libs.utils import is_cached, cache_last_modified, read_cache, \
                            write_cache, warning, available_colors


config = ConfigParser()

if not config.read(os.path.expanduser('~/.mpdc')):
    warning('Can\'t read the configuration file, please run mpdc-configure')
    sys.exit(0)

try:
    config['mpd']['host']
    config['mpd']['password']
    config['mpd']['port']
    config['mpdc']['collections']
except KeyError:
    warning('Invalid configuration file')
    sys.exit(0)

colors = ['none', 'none', 'none']
if 'colors' in config['mpdc']:
    user_colors = [s.strip() for s in config['mpdc']['colors'].split(',')]
    if (len(user_colors) == 3 and
        all(color in available_colors for color in user_colors)):
        colors = user_colors