Example #1
0
    def album_distance(self, items, album_info, mapping):
        dist = hooks.Distance()

        # check if the album has a log file (from EAC/XLD):
        release_ids = _process_items(items)
        has_log = release_ids is not None

        # get bitdepths and samplerates
        bitdepths = set(map(lambda item: item.bitdepth, items))
        samplerates = set(map(lambda item: item.samplerate, items))

        # Boolean flags to determine media type
        is_not_cd = max(bitdepths) > 16 or max(samplerates) != 44100
        could_be_cd = not is_not_cd
        candidate_media_is_cd = \
            "CD" in album_info.media.upper() if album_info.media else False

        # penalty for CDs if it's clearly not a CD
        if is_not_cd and candidate_media_is_cd:
            dist.add('media', self.config['media_weight'].as_number())
            album_info.data_source+='+' + ui.colorize('text_warning', 'guess_media_NOT_A_CD')

        # penalty if we think it's a CD (found a log file and
        # bitdepths/samplerates are correct) but the candidate media is wrong:
        if has_log and could_be_cd and not candidate_media_is_cd:
            dist.add('media', self.config['media_weight'].as_number())
            album_info.data_source+='+' + ui.colorize('text_warning', 'guess_media_IS_A_CD')

        # penalty if we found an album id from the log file,
        # and the album id does not match:
        if release_ids is not None and album_info.album_id not in release_ids:
            dist.add('album_id', self.config['album_id_weight'].as_number())
            album_info.data_source+='+' + ui.colorize('text_warning', 'guess_media_ALBUM_ID_FROM_LOG_WRONG')

        return dist
Example #2
0
    def check_bad(self, lib, opts, args):
        for item in lib.items(ui.decargs(args)):

            # First, check whether the path exists. If not, the user
            # should probably run `beet update` to cleanup your library.
            dpath = displayable_path(item.path)
            self._log.debug("checking path: {}", dpath)
            if not os.path.exists(item.path):
                ui.print_("{}: file does not exist".format(
                    ui.colorize('text_error', dpath)))

            # Run the checker against the file if one is found
            ext = os.path.splitext(item.path)[1][1:]
            checker = self.get_checker(ext)
            if not checker:
                continue
            path = item.path
            if not isinstance(path, unicode):
                path = item.path.decode(sys.getfilesystemencoding())
            status, errors, output = checker(path)
            if status > 0:
                ui.print_("{}: checker exited withs status {}"
                          .format(ui.colorize('text_error', dpath), status))
                for line in output:
                    ui.print_("  {}".format(displayable_path(line)))
            elif errors > 0:
                ui.print_("{}: checker found {} errors or warnings"
                          .format(ui.colorize('text_warning', dpath), errors))
                for line in output:
                    ui.print_("  {}".format(displayable_path(line)))
            else:
                ui.print_("{}: ok".format(ui.colorize('text_success', dpath)))
Example #3
0
 def search(self, lib, opts, args):
     password = config['gmusic']['password']
     email = config['gmusic']['email']
     password.redact = True
     email.redact = True
     # Since Musicmanager doesn't support library management
     # we need to use mobileclient interface
     mobile = Mobileclient()
     try:
         mobile.login(email.as_str(), password.as_str(),
                      Mobileclient.FROM_MAC_ADDRESS)
         files = mobile.get_all_songs()
     except NotLoggedIn:
         ui.print_(
             u'Authentication error. Please check your email and password.'
         )
         return
     if not args:
         for i, file in enumerate(files, start=1):
             print(i, ui.colorize('blue', file['artist']),
                   file['title'], ui.colorize('red', file['album']))
     else:
         if opts.track:
             self.match(files, args, 'title')
         else:
             self.match(files, args, 'artist')
Example #4
0
def play_music(lib, opts, args):
    """Execute query, create temporary playlist and execute player
    command passing that playlist.
    """

    command = config['play']['command'].get()

    # If a command isn't set then let the OS decide how to open the playlist.
    if not command:
        sys_name = platform.system()
        if sys_name == 'Darwin':
            command = 'open'
        elif sys_name == 'Windows':
            command = 'start'
        else:
            # If not Mac or Win then assume Linux(or posix based).
            command = 'xdg-open'

    # Preform search by album and add folders rather then tracks to playlist.
    if opts.album:
        albums = lib.albums(ui.decargs(args))
        paths = []

        for album in albums:
            paths.append(album.item_dir())
        item_type = 'album'

    # Preform item query and add tracks to playlist.
    else:
        paths = [item.path for item in lib.items(ui.decargs(args))]
        item_type = 'track'

    item_type += 's' if len(paths) > 1 else ''

    if not paths:
        ui.print_(ui.colorize('yellow', 'No {0} to play.'.format(item_type)))
        return

    # Warn user before playing any huge playlists.
    if len(paths) > 100:
        ui.print_(
            ui.colorize(
                'yellow', 'You are about to queue {0} {1}.'.format(
                    len(paths), item_type)))

        if ui.input_options(('Continue', 'Abort')) == 'a':
            return

    # Create temporary m3u file to hold our playlist.
    m3u = NamedTemporaryFile('w', suffix='.m3u', delete=False)
    for item in paths:
        m3u.write(item + '\n')
    m3u.close()

    # Invoke the command and log the output.
    output = util.command_output([command, m3u.name])
    if output:
        log.debug(u'Output of {0}: {1}'.format(command, output))

    ui.print_(u'Playing {0} {1}.'.format(len(paths), item_type))
Example #5
0
    def metadata_retriever(
        self, lib, albums
    ):  #Get album cover for each of the albums. This implements the metadata_retriever CLI command.

        for album in albums:
            if (album.artpath and os.path.isfile(album.artpath)):
                message = ui.colorize('action', 'already has cover art')
                self._log.info('{0}: {1}', album,
                               message)  #prints out to command line
            else:
                localpath = [album.path]

                start_time = datetime.datetime.now()
                result = self.source[0].get(album, self, localpath)
                end_time = datetime.datetime.now()

                if (result):
                    image = True
                else:
                    image = None

                if (image):  #if the album art is found
                    album.store()  #storing the changes in the database
                    message = ui.colorize('text_success',
                                          'found cover art')  #print in green
                else:
                    message = ui.colorize('text_error',
                                          'cover art not found')  #print in red

                self._log.info('{0}: {1}', album,
                               message)  #prints out to command line

                print("Time for fetching cover art: ", end_time - start_time)
Example #6
0
    def getlyrics(self, lib,
                  item):  #get lyrics from web and store them in the database

        if (item.lyrics):  #if lyrics already exists
            message = ui.colorize('text_highlight', 'lyrics already exist')
            self._log.info('{0}: {1}', message,
                           item)  #prints out to command line
            return

        lyrics = self.backends[0].fetch(
            item.artist,
            item.title)  #call fetch function defined in Genius class

        if (lyrics):  #if we find the lyrics
            message = ui.colorize('text_success', 'fetched lyrics')
            self._log.info('{0}: {1}', message,
                           item)  #prints out to command line
        else:  #if lyrics not found
            message = ui.colorize('text_error', 'lyrics not found')
            self._log.info('{0}: {1}', message,
                           item)  #prints out to command line
            default_lyrics = None  #default_lyrics value is defined as None
            lyrics = default_lyrics

        item.lyrics = lyrics.strip(
        )  #assign lyrics to item's lyrics deleting whitespaces at the beginning and at the end of the text
        item.lyrics = re.sub(r"[\(\[].*?[\)\]]", "", item.lyrics)
        item.store()  #store item in the database
Example #7
0
 def search(self, lib, opts, args):
     password = config['gmusic']['password']
     email = config['gmusic']['email']
     password.redact = True
     email.redact = True
     # Since Musicmanager doesn't support library management
     # we need to use mobileclient interface
     mobile = Mobileclient()
     try:
         mobile.login(email.as_str(), password.as_str(),
                      Mobileclient.FROM_MAC_ADDRESS)
         files = mobile.get_all_songs()
     except NotLoggedIn:
         ui.print_(
             u'Authentication error. Please check your email and password.')
         return
     if not args:
         for i, file in enumerate(files, start=1):
             print(i, ui.colorize('blue', file['artist']), file['title'],
                   ui.colorize('red', file['album']))
     else:
         if opts.track:
             self.match(files, args, 'title')
         else:
             self.match(files, args, 'artist')
Example #8
0
def fetch_review(album, log, force):
    rating = album.get('pitchfork_score')
    if rating != None and rating != '' and not force:
        message = ui.colorize('text_highlight_minor',
                              u'has rating %s' % rating)
        log.info(u'{0}: {1}', album, message)
        return

    try:
        log.debug(u'Querying {0.albumartist} - {0.album}', album)
        review = search(album['albumartist'], album['album'])
        score = float(review.score())
    except IndexError as e:
        log.debug(u'No review found: {0}', e)
        message = ui.colorize('text_error', u'no review found')
        log.info(u'{0}: {1}', album, message)
        return
    except Exception as e:
        log.debug(u'Error trying to get review: {0}', e)
        message = ui.colorize('text_error', u'could not fetch review')
        log.info(u'{0}: {1}', album, message)
        return

    message = ui.colorize('text_success', u'found review %s' % review.score())
    album['pitchfork_bnm'] = review.best_new_music()
    album['pitchfork_description'] = review.abstract()
    album['pitchfork_score'] = score
    album['pitchfork_url'] = 'https://pitchfork.com%s' % review.url
    album.store()
    log.info(u'{0}: {1}', album, message)
Example #9
0
File: play.py Project: 241n/beets
def play_music(lib, opts, args):
    """Execute query, create temporary playlist and execute player
    command passing that playlist.
    """

    command = config['play']['command'].get()

    # If a command isn't set then let the OS decide how to open the playlist.
    if not command:
        sys_name = platform.system()
        if sys_name == 'Darwin':
            command = 'open'
        elif sys_name == 'Windows':
            command = 'start'
        else:
            # If not Mac or Win then assume Linux(or posix based).
            command = 'xdg-open'

    # Preform search by album and add folders rather then tracks to playlist.
    if opts.album:
        albums = lib.albums(ui.decargs(args))
        paths = []

        for album in albums:
            paths.append(album.item_dir())
        item_type = 'album'

    # Preform item query and add tracks to playlist.
    else:
        paths = [item.path for item in lib.items(ui.decargs(args))]
        item_type = 'track'

    item_type += 's' if len(paths) > 1 else ''

    if not paths:
        ui.print_(ui.colorize('yellow', 'No {0} to play.'.format(item_type)))
        return

    # Warn user before playing any huge playlists.
    if len(paths) > 100:
        ui.print_(ui.colorize(
            'yellow',
            'You are about to queue {0} {1}.'.format(len(paths), item_type)))

        if ui.input_options(('Continue', 'Abort')) == 'a':
            return

    # Create temporary m3u file to hold our playlist.
    m3u = NamedTemporaryFile('w', suffix='.m3u', delete=False)
    for item in paths:
        m3u.write(item + '\n')
    m3u.close()

    # Invoke the command and log the output.
    output = util.command_output([command, m3u.name])
    if output:
        log.debug(u'Output of {0}: {1}'.format(command, output))

    ui.print_(u'Playing {0} {1}.'.format(len(paths), item_type))
Example #10
0
def show_change(cur_artist, cur_album, items, info, dist, color=True):
    """Print out a representation of the changes that will be made if
    tags are changed from (cur_artist, cur_album, items) to info with
    distance dist.
    """
    def show_album(artist, album):
        if artist:
            print_('    %s - %s' % (artist, album))
        else:
            print_('    %s' % album)

    # Identify the album in question.
    if cur_artist != info['artist'] or \
            (cur_album != info['album'] and info['album'] != VARIOUS_ARTISTS):
        artist_l, artist_r = cur_artist or '', info['artist']
        album_l,  album_r  = cur_album  or '', info['album']
        if artist_r == VARIOUS_ARTISTS:
            # Hide artists for VA releases.
            artist_l, artist_r = u'', u''

        if color:
            artist_l, artist_r = ui.colordiff(artist_l, artist_r)
            album_l, album_r   = ui.colordiff(album_l, album_r)

        print_("Correcting tags from:")
        show_album(artist_l, album_l)
        print_("To:")
        show_album(artist_r, album_r)
    else:
        print_("Tagging: %s - %s" % (info['artist'], info['album']))

    # Distance/similarity.
    print_('(Similarity: %s)' % dist_string(dist, color))

    # Tracks.
    for i, (item, track_data) in enumerate(zip(items, info['tracks'])):
        cur_track = str(item.track)
        new_track = str(i+1)
        cur_title = item.title
        new_title = track_data['title']
        
        # Possibly colorize changes.
        if color:
            cur_title, new_title = ui.colordiff(cur_title, new_title)
            if cur_track != new_track:
                cur_track = ui.colorize('red', cur_track)
                new_track = ui.colorize('red', new_track)
        
        if cur_title != new_title and cur_track != new_track:
            print_(" * %s (%s) -> %s (%s)" % (
                cur_title, cur_track, new_title, new_track
            ))
        elif cur_title != new_title:
            print_(" * %s -> %s" % (cur_title, new_title))
        elif cur_track != new_track:
            print_(" * %s (%s -> %s)" % (item.title, cur_track, new_track))
Example #11
0
def show_change(cur_artist, cur_album, items, info, dist, color=True):
    """Print out a representation of the changes that will be made if
    tags are changed from (cur_artist, cur_album, items) to info with
    distance dist.
    """
    def show_album(artist, album):
        if artist:
            print_('    %s - %s' % (artist, album))
        else:
            print_('    %s' % album)

    # Identify the album in question.
    if cur_artist != info['artist'] or \
            (cur_album != info['album'] and info['album'] != VARIOUS_ARTISTS):
        artist_l, artist_r = cur_artist or '', info['artist']
        album_l, album_r = cur_album or '', info['album']
        if artist_r == VARIOUS_ARTISTS:
            # Hide artists for VA releases.
            artist_l, artist_r = u'', u''

        if color:
            artist_l, artist_r = ui.colordiff(artist_l, artist_r)
            album_l, album_r = ui.colordiff(album_l, album_r)

        print_("Correcting tags from:")
        show_album(artist_l, album_l)
        print_("To:")
        show_album(artist_r, album_r)
    else:
        print_("Tagging: %s - %s" % (info['artist'], info['album']))

    # Distance/similarity.
    print_('(Similarity: %s)' % dist_string(dist, color))

    # Tracks.
    for i, (item, track_data) in enumerate(zip(items, info['tracks'])):
        cur_track = str(item.track)
        new_track = str(i + 1)
        cur_title = item.title
        new_title = track_data['title']

        # Possibly colorize changes.
        if color:
            cur_title, new_title = ui.colordiff(cur_title, new_title)
            if cur_track != new_track:
                cur_track = ui.colorize('red', cur_track)
                new_track = ui.colorize('red', new_track)

        if cur_title != new_title and cur_track != new_track:
            print_(" * %s (%s) -> %s (%s)" %
                   (cur_title, cur_track, new_title, new_track))
        elif cur_title != new_title:
            print_(" * %s -> %s" % (cur_title, new_title))
        elif cur_track != new_track:
            print_(" * %s (%s -> %s)" % (item.title, cur_track, new_track))
Example #12
0
        def tag(mf, lyrics):
            try:
                if( lyrics ):
                    mf.lyrics = lyrics
                    mf.save()

                    print_("    -%s:" % (mf.title), ui.colorize('green', 'Updated!'))
                else:
                    print_("    -%s: " % (mf.title), ui.colorize('red', 'Not Found'))
            except:
                return
Example #13
0
 def list_tools(self):
     checkers = [(checker.name, checker.available())
                 for checker in IntegrityChecker.all()]
     prog_length = max(map(lambda c: len(c[0]), checkers)) + 3
     for name, available in checkers:
         msg = name + (prog_length - len(name)) * u' '
         if available:
             msg += colorize('green', u'found')
         else:
             msg += colorize('red', u'not found')
         print(msg)
Example #14
0
 def list_tools(self):
     checkers = [(checker.name, checker.available())
                 for checker in IntegrityChecker.all()]
     prog_length = max(map(lambda c: len(c[0]), checkers)) + 3
     for name, available in checkers:
         msg = name + (prog_length-len(name))*u' '
         if available:
             msg += colorize('green', u'found')
         else:
             msg += colorize('red', u'not found')
         print(msg)
Example #15
0
 def _update_cover(self, artist_info, force):
     all_exist = FetchArtistPlugin._check_for_existing_covers(artist_info)
     if force or not all_exist:
         if self._fetch_cover(artist_info):
             self._write_covers(artist_info, force)
             message = ui.colorize('text_success', 'artist cover found')
         else:
             message = ui.colorize('text_error', 'no artist cover found')
     else:
         message = ui.colorize('text_highlight_minor', 'has artist cover')
     self._log.info(u'{0}: {1}', artist_info.name, message)
Example #16
0
def dist_string(dist):
    """Formats a distance (a float) as a colorized similarity percentage
    string.
    """
    out = '%.1f%%' % ((1 - dist) * 100)
    if dist <= config['match']['strong_rec_thresh'].as_number():
        out = ui.colorize('green', out)
    elif dist <= config['match']['medium_rec_thresh'].as_number():
        out = ui.colorize('yellow', out)
    else:
        out = ui.colorize('red', out)
    return out
Example #17
0
def dist_string(dist):
    """Formats a distance (a float) as a similarity percentage string.
    The string is colorized if color is True.
    """
    out = '%.1f%%' % ((1 - dist) * 100)
    if dist <= autotag.STRONG_REC_THRESH:
        out = ui.colorize('green', out)
    elif dist <= autotag.MEDIUM_REC_THRESH:
        out = ui.colorize('yellow', out)
    else:
        out = ui.colorize('red', out)
    return out
Example #18
0
def dist_string(dist):
    """Formats a distance (a float) as a colorized similarity percentage
    string.
    """
    out = '%.1f%%' % ((1 - dist) * 100)
    if dist <= config['match']['strong_rec_thresh'].as_number():
        out = ui.colorize('green', out)
    elif dist <= config['match']['medium_rec_thresh'].as_number():
        out = ui.colorize('yellow', out)
    else:
        out = ui.colorize('red', out)
    return out
Example #19
0
def dist_string(dist):
    """Formats a distance (a float) as a colorized similarity percentage
    string.
    """
    out = "%.1f%%" % ((1 - dist) * 100)
    if dist <= config["match"]["strong_rec_thresh"].as_number():
        out = ui.colorize("green", out)
    elif dist <= config["match"]["medium_rec_thresh"].as_number():
        out = ui.colorize("yellow", out)
    else:
        out = ui.colorize("red", out)
    return out
Example #20
0
    def check_item(self, item):
        # First, check whether the path exists. If not, the user
        # should probably run `beet update` to cleanup your library.
        dpath = displayable_path(item.path)
        self._log.debug("checking path: {}", dpath)
        if not os.path.exists(item.path):
            ui.print_("{}: file does not exist".format(
                ui.colorize('text_error', dpath)))

        # Run the checker against the file if one is found
        ext = os.path.splitext(item.path)[1][1:].decode('utf8', 'ignore')
        checker = self.get_checker(ext)
        if not checker:
            self._log.error("no checker specified in the config for {}",
                            ext)
            return []
        path = item.path
        if not isinstance(path, str):
            path = item.path.decode(sys.getfilesystemencoding())
        try:
            status, errors, output = checker(path)
        except CheckerCommandException as e:
            if e.errno == errno.ENOENT:
                self._log.error(
                    "command not found: {} when validating file: {}",
                    e.checker,
                    e.path
                )
            else:
                self._log.error("error invoking {}: {}", e.checker, e.msg)
            return []

        error_lines = []

        if status > 0:
            error_lines.append(
                "{}: checker exited with status {}"
                .format(ui.colorize('text_error', dpath), status))
            for line in output:
                error_lines.append(f"  {line}")

        elif errors > 0:
            error_lines.append(
                    "{}: checker found {} errors or warnings"
                    .format(ui.colorize('text_warning', dpath), errors))
            for line in output:
                error_lines.append(f"  {line}")
        elif self.verbose:
            error_lines.append(
                "{}: ok".format(ui.colorize('text_success', dpath)))

        return error_lines
Example #21
0
def dist_string(config, dist, color):
    """Formats a distance (a float) as a similarity percentage string.
    The string is colorized if color is True.
    """
    out = '%.1f%%' % ((1 - dist) * 100)
    if color:
        if dist <= config.strong_rec_thresh:
            out = ui.colorize('green', out)
        elif dist <= config.medium_rec_thresh:
            out = ui.colorize('yellow', out)
        else:
            out = ui.colorize('red', out)
    return out
Example #22
0
def dist_string(dist, color):
    """Formats a distance (a float) as a similarity percentage string.
    The string is colorized if color is True.
    """
    out = "%.1f%%" % ((1 - dist) * 100)
    if color:
        if dist <= autotag.STRONG_REC_THRESH:
            out = ui.colorize("green", out)
        elif dist <= autotag.MEDIUM_REC_THRESH:
            out = ui.colorize("yellow", out)
        else:
            out = ui.colorize("red", out)
    return out
Example #23
0
def dist_string(dist, color):
    """Formats a distance (a float) as a string. The string is
    colorized if color is True.
    """
    out = str(dist)
    if color:
        if dist <= autotag.STRONG_REC_THRESH:
            out = ui.colorize('green', out)
        elif dist <= autotag.MEDIUM_REC_THRESH:
            out = ui.colorize('yellow', out)
        else:
            out = ui.colorize('red', out)
    return out
Example #24
0
def dist_string(dist, color):
    """Formats a distance (a float) as a similarity percentage string.
    The string is colorized if color is True.
    """
    out = '%.1f%%' % ((1 - dist) * 100)
    if color:
        if dist <= autotag.STRONG_REC_THRESH:
            out = ui.colorize('green', out)
        elif dist <= autotag.MEDIUM_REC_THRESH:
            out = ui.colorize('yellow', out)
        else:
            out = ui.colorize('red', out)
    return out
Example #25
0
 def check(item):
     try:
         verify_checksum(item)
         if self.check_integrity:
             verify_integrity(item)
         log.debug('{}: {}'.format(colorize('green', 'OK'), item.path))
     except ChecksumError:
         log.error('{}: {}'.format(colorize('red', 'FAILED'), item.path))
         status['failures'] += 1
     except IntegrityError as ex:
         log.warn('{} {}: {}'.format(colorize('yellow', 'WARNING'),
                                     ex.reason, item.path))
         status['integrity'] += 1
Example #26
0
    def _update_cover(self, artist_info, force):
        all_exist = FetchArtistPlugin._check_for_existing_covers(artist_info)
        if force or not all_exist:
            if self._fetch_cover(artist_info):
                if self._write_covers(artist_info, force):
                    message = ui.colorize('text_success', 'artist cover found')
                else:
                    message = ui.colorize('text_error', 'path not found')
            else:
                message = ui.colorize('text_error', 'no artist cover found')
        else:
            message = ui.colorize('text_highlight_minor', 'has artist cover')

        self._log.info(u'{0}: {1}', artist_info.name, message)
Example #27
0
 def find_items_in_lib(self, lib, track_names, artist_name):
     """Returns a list of items found, and list of items not found in library
     from a given list of track names.
     """
     items, missing_items = [], []
     for track_nr, track_name in enumerate(track_names):
         item = _find_item_in_lib(lib, track_name, artist_name)
         if item:
             items += [item]
             message = ui.colorize('text_success', u'found')
         else:
             missing_items += [item]
             message = ui.colorize('text_error', u'not found')
         self._log.info("{0} {1}: {2}".format(
                       (track_nr+1), track_name, message))
     return items, missing_items
Example #28
0
 def update(item):
     log.debug(u'updating checksum: {}'
               .format(displayable_path(item.path)))
     try:
         set_checksum(item)
     except IOError as exc:
         log.error(u'{} {}'.format(colorize('red', u'ERROR'), exc))
Example #29
0
 def check(item):
     try:
         if 'checksum' in item:
             verify_checksum(item)
         fixer = IntegrityChecker.fixer(item)
         if fixer:
             fixer.check(item)
             log.debug(u'{}: {}'.format(colorize('green', u'OK'),
                                        displayable_path(item.path)))
     except IntegrityError:
         failed.append(item)
     except ChecksumError:
         log.error(u'{}: {}'.format(colorize('red', u'FAILED checksum'),
                                    displayable_path(item.path)))
     except IOError as exc:
         log.error(u'{} {}'.format(colorize('red', u'ERROR'), exc))
Example #30
0
 def check(item):
     try:
         if 'checksum' in item:
             verify_checksum(item)
         fixer = IntegrityChecker.fixer(item)
         if fixer:
             fixer.check(item)
             log.debug(u'{}: {}'.format(colorize('green', u'OK'),
                                        displayable_path(item.path)))
     except IntegrityError:
         failed.append(item)
     except ChecksumError:
         log.error(u'{}: {}'.format(colorize('red', u'FAILED checksum'),
                                    displayable_path(item.path)))
     except IOError as exc:
         log.error(u'{} {}'.format(colorize('red', u'ERROR'), exc))
Example #31
0
 def fix(item):
     fixer = IntegrityChecker.fixer(item)
     if fixer:
         fixer.fix(item)
         log.debug(u'{}: {}'.format(colorize('green', u'FIXED'),
                                    displayable_path(item.path)))
         set_checksum(item)
Example #32
0
 def fix(item):
     fixer = IntegrityChecker.fixer(item)
     if fixer:
         fixer.fix(item)
         log.debug(u'{}: {}'.format(colorize('green', u'FIXED'),
                                    displayable_path(item.path)))
         set_checksum(item)
Example #33
0
 def update(item):
     log.debug(u'updating checksum: {}'.format(
         displayable_path(item.path)))
     try:
         set_checksum(item)
     except IOError as exc:
         log.error(u'{} {}'.format(colorize('red', u'ERROR'), exc))
Example #34
0
 def fetch(mf):
     try:
         print_("    -%s:" % (mf.title), ui.colorize('yellow', 'Fetching'))
         lyrics = self.fetchLyrics(scrub(mf.artist), scrub(mf.title))
         result = (mf, lyrics);
         return result
     except:
         return None
Example #35
0
        def func(lib, opts, args):  #main functionalities of the plugin

            print("\n")
            print("Please run the command with one of the following options: ")
            print("-c or --cover for finding the album cover")
            print("-l or --lyric for finding lyrics")
            print("-a or --all for finding the cover arts for all releases")
            print("-p or --print for printing lyrics to command line")
            print(
                "-w or --write for writing lyrics to a file and creating a word cloud"
            )
            print("\n\n")

            if (opts.coverart):

                self.metadata_retriever(lib, lib.albums(ui.decargs(args)))
                print("\n")

            albums = lib.albums(
                ui.decargs(args))  #from database we reach out to items table
            for album in albums:
                if (opts.allreleases):
                    start_time = datetime.datetime.now()
                    self.allreleases(lib, album)
                    end_time = datetime.datetime.now()

                    print("Time for fetching all cover arts: ",
                          end_time - start_time)

            items = lib.items(
                ui.decargs(args))  #from database we reach out to items table

            for item in items:  #for each item in items table

                if (opts.lyrics):
                    start_time = datetime.datetime.now()
                    self.getlyrics(lib, item)  #call getlyrics function
                    end_time = datetime.datetime.now()
                    duration = end_time - start_time

                    print("Time for fetching lyrics: ", end_time - start_time)

                if (item.lyrics):  #if the lyrics are found
                    if (opts.printlyrics):  #if there is a -p or --print option
                        title = item.artist + " - " + item.title
                        title = ui.colorize('action', title)
                        ui.print_(title)
                        ui.print_(item.lyrics)  #print lyrics to console
                        ui.print_(
                            "\n")  #print a space character after each song
                    if (opts.writetofile):  #if there is a -w or --write option
                        start_time = datetime.datetime.now()
                        self.writetofile(lib, item)  #writing lyrics to file
                        end_time = datetime.datetime.now()

                        print(
                            "Time for writing {} to file : ".format(
                                item.title), end_time - start_time)
Example #36
0
    def check_bad(self, lib, opts, args):
        for item in lib.items(ui.decargs(args)):

            # First, check whether the path exists. If not, the user
            # should probably run `beet update` to cleanup your library.
            dpath = displayable_path(item.path)
            self._log.debug(u"checking path: {}", dpath)
            if not os.path.exists(item.path):
                ui.print_(u"{}: file does not exist".format(
                    ui.colorize('text_error', dpath)))

            # Run the checker against the file if one is found
            ext = os.path.splitext(item.path)[1][1:].decode('utf8', 'ignore')
            checker = self.get_checker(ext)
            if not checker:
                self._log.error(u"no checker specified in the config for {}",
                                ext)
                continue
            path = item.path
            if not isinstance(path, six.text_type):
                path = item.path.decode(sys.getfilesystemencoding())
            try:
                status, errors, output = checker(path)
            except CheckerCommandException as e:
                if e.errno == errno.ENOENT:
                    self._log.error(
                        u"command not found: {} when validating file: {}",
                        e.checker,
                        e.path
                    )
                else:
                    self._log.error(u"error invoking {}: {}", e.checker, e.msg)
                continue
            if status > 0:
                ui.print_(u"{}: checker exited with status {}"
                          .format(ui.colorize('text_error', dpath), status))
                for line in output:
                    ui.print_(u"  {}".format(displayable_path(line)))
            elif errors > 0:
                ui.print_(u"{}: checker found {} errors or warnings"
                          .format(ui.colorize('text_warning', dpath), errors))
                for line in output:
                    ui.print_(u"  {}".format(displayable_path(line)))
            elif opts.verbose:
                ui.print_(u"{}: ok".format(ui.colorize('text_success', dpath)))
Example #37
0
 def add(item):
     log.debug('adding checksum for {0}'.format(item.path))
     set_checksum(item)
     if self.check_integrity:
         try:
             verify_integrity(item)
         except IntegrityError as ex:
             log.warn('{} {}: {}'.format(colorize('yellow', 'WARNING'),
                                         ex.reason, item.path))
Example #38
0
    def before_choose(self, session, task):
        """Prints a helpful message to tell which candidate corresponds to the
        scanned barcodes.
        This is useful to quickly see if the chosen release is the correct one.
        """

        # Note: task.candidates = list of AlbumMatch
        if not task.candidates:
            return None

        ids = set()
        barcodes = set()
        for candidate in task.candidates:
            # TODO we don't have to check ALL candidates,
            # because they all use the same file paths..
            tracks = candidate.mapping
            paths = set(map(lambda i: os.path.dirname(i.path), tracks))
            for path in paths:
                if path in _matches:
                    ids.update(_matches[path].album_ids)
                    barcodes.update(_matches[path].barcodes)
        if len(barcodes) == 0:
            return None

        #print("------------------------")
        if len(ids) == 0:
            print("{}: {}".format(
                ui.colorize('text_warning',
                            "Found barcode(s) but no matching releases"),
                ' '.join(barcodes)))
        else:
            print("{}: {}".format(
                ui.colorize('text_success', "Found barcode(s)"),
                ' '.join(barcodes)))
        #    print("Candidates with matching IDs:")
        #    for index, candidate in enumerate(task.candidates):
        #        info = candidate.info
        #        if info.album_id in ids:
        #            print(u"{:2d}. {}".format(index + 1, _get_debug_str(info)))
        #print("------------------------")

        return None
Example #39
0
 def check(item):
     try:
         if external:
             verify_integrity(item)
         elif item.get('checksum', None):
             verify_checksum(item)
         log.debug(u'{}: {}'.format(colorize('green', u'OK'),
                                    displayable_path(item.path)))
     except ChecksumError:
         log.error(u'{}: {}'.format(colorize('red', u'FAILED'),
                                    displayable_path(item.path)))
         failures[0] += 1
     except IntegrityError as ex:
         log.warn(u'{} {}: {}'.format(colorize('yellow', u'WARNING'),
                                      ex.reason,
                                      displayable_path(item.path)))
         failures[0] += 1
     except IOError as exc:
         log.error(u'{} {}'.format(colorize('red', u'ERROR'), exc))
         failures[0] += 1
Example #40
0
 def add(item):
     log.debug(u'adding checksum for {0}'.format(
         displayable_path(item.path)))
     set_checksum(item)
     if self.check_integrity:
         try:
             verify_integrity(item)
         except IntegrityError as ex:
             log.warn(u'{} {}: {}'.format(
                 colorize('yellow', u'WARNING'), ex.reason,
                 displayable_path(item.path)))
Example #41
0
def automigrate():
    """Migrate the configuration, database, and state files. If any
    migration occurs, print out a notice with some helpful next steps.
    """
    config_fn = migrate_config()
    db_fn = migrate_db()
    migrate_state()

    if config_fn:
        ui.print_(ui.colorize('fuchsia', u'MIGRATED CONFIGURATION'))

        ui.print_(
            CONFIG_MIGRATED_MESSAGE.format(
                newconfig=util.displayable_path(config_fn)))
        if db_fn:
            ui.print_(
                DB_MIGRATED_MESSAGE.format(newdb=util.displayable_path(db_fn)))

        ui.input_(ui.colorize('fuchsia', u'Press ENTER to continue:'))
        ui.print_()
Example #42
0
 def check(item):
     try:
         if external:
             verify_integrity(item)
         elif item.get('checksum', None):
             verify_checksum(item)
         log.debug(u'{}: {}'.format(colorize('green', u'OK'),
                                    displayable_path(item.path)))
     except ChecksumError:
         log.error(u'{}: {}'.format(colorize('red', u'FAILED'),
                                    displayable_path(item.path)))
         failures[0] += 1
     except IntegrityError as ex:
         log.warn(u'{} {}: {}'.format(colorize('yellow', u'WARNING'),
                                      ex.reason,
                                      displayable_path(item.path)))
         failures[0] += 1
     except IOError as exc:
         log.error(u'{} {}'.format(colorize('red', u'ERROR'), exc))
         failures[0] += 1
Example #43
0
def automigrate():
    """Migrate the configuration, database, and state files. If any
    migration occurs, print out a notice with some helpful next steps.
    """
    config_fn = migrate_config()
    db_fn = migrate_db()
    migrate_state()

    if config_fn:
        ui.print_(ui.colorize('fuchsia', u'MIGRATED CONFIGURATION'))

        ui.print_(CONFIG_MIGRATED_MESSAGE.format(
            newconfig=util.displayable_path(config_fn))
        )
        if db_fn:
            ui.print_(DB_MIGRATED_MESSAGE.format(
                newdb=util.displayable_path(db_fn)
            ))

        ui.input_(ui.colorize('fuchsia', u'Press ENTER to continue:'))
        ui.print_()
Example #44
0
    def batch_fetch_art(self, lib, albums, force):
        """Fetch album art for each of the albums. This implements the manual
        fetchart CLI command.
        """
        for album in albums:
            if album.artpath and not force and os.path.isfile(album.artpath):
                message = ui.colorize('text_highlight_minor', u'has album art')
            else:
                # In ordinary invocations, look for images on the
                # filesystem. When forcing, however, always go to the Web
                # sources.
                local_paths = None if force else [album.path]

                candidate = self.art_for_album(album, local_paths)
                if candidate:
                    self._set_art(album, candidate)
                    message = ui.colorize('text_success', u'found album art')
                else:
                    message = ui.colorize('text_error', u'no art found')

            self._log.info(u'{0}: {1}', album, message)
Example #45
0
def show_change(cur_artist, cur_album, items, info, dist, color=True):
    """Print out a representation of the changes that will be made if
    tags are changed from (cur_artist, cur_album, items) to info with
    distance dist.
    """
    if cur_artist != info['artist'] or cur_album != info['album']:
        artist_l, artist_r = cur_artist or '', info['artist']
        album_l,  album_r  = cur_album  or '', info['album']
        if color:
            artist_l, artist_r = ui.colordiff(artist_l, artist_r)
            album_l, album_r   = ui.colordiff(album_l, album_r)
        print_("Correcting tags from:")
        print_('     %s - %s' % (artist_l, album_l))
        print_("To:")
        print_('     %s - %s' % (artist_r, album_r))
    else:
        print_("Tagging: %s - %s" % (info['artist'], info['album']))
    print_('(Distance: %s)' % dist_string(dist, color))
    for i, (item, track_data) in enumerate(zip(items, info['tracks'])):
        cur_track = str(item.track)
        new_track = str(i+1)
        cur_title = item.title
        new_title = track_data['title']
        
        # Possibly colorize changes.
        if color:
            cur_title, new_title = ui.colordiff(cur_title, new_title)
            if cur_track != new_track:
                cur_track = ui.colorize('red', cur_track)
                new_track = ui.colorize('red', new_track)
        
        if cur_title != new_title and cur_track != new_track:
            print_(" * %s (%s) -> %s (%s)" % (
                cur_title, cur_track, new_title, new_track
            ))
        elif cur_title != new_title:
            print_(" * %s -> %s" % (cur_title, new_title))
        elif cur_track != new_track:
            print_(" * %s (%s -> %s)" % (item.title, cur_track, new_track))
Example #46
0
    def batch_fetch_art(self, lib, albums, force):
        """Fetch album art for each of the albums. This implements the manual
        fetchart CLI command.
        """
        for album in albums:
            if album.artpath and not force:
                message = 'has album art'
            else:
                # In ordinary invocations, look for images on the
                # filesystem. When forcing, however, always go to the Web
                # sources.
                local_paths = None if force else [album.path]

                path = self.art_for_album(album, local_paths)
                if path:
                    album.set_art(path, False)
                    album.store()
                    message = ui.colorize('green', 'found album art')
                else:
                    message = ui.colorize('red', 'no art found')

            self._log.info(u'{0}: {1}', album, message)
Example #47
0
    def batch_fetch_art(self, lib, albums, force):
        """Fetch album art for each of the albums. This implements the manual
        fetchart CLI command.
        """
        for album in albums:
            if album.artpath and not force:
                message = 'has album art'
            else:
                # In ordinary invocations, look for images on the
                # filesystem. When forcing, however, always go to the Web
                # sources.
                local_paths = None if force else [album.path]

                path = self.art_for_album(album, local_paths)
                if path:
                    album.set_art(path, False)
                    album.store()
                    message = ui.colorize('text_success', 'found album art')
                else:
                    message = ui.colorize('text_error', 'no art found')

            self._log.info(u'{0}: {1}', album, message)
Example #48
0
def batch_fetch_art(lib, albums, force, maxwidth=None):
    """Fetch album art for each of the albums. This implements the manual
    fetchart CLI command.
    """
    for album in albums:
        if album.artpath and not force:
            message = "has album art"
        else:
            # In ordinary invocations, look for images on the
            # filesystem. When forcing, however, always go to the Web
            # sources.
            local_paths = None if force else [album.path]

            path = art_for_album(album, local_paths, maxwidth)
            if path:
                album.set_art(path, False)
                album.store()
                message = ui.colorize("green", "found album art")
            else:
                message = ui.colorize("red", "no art found")

        log.info(u"{0} - {1}: {2}".format(album.albumartist, album.album, message))
Example #49
0
def penalty_string(distance, limit=None):
    """Returns a colorized string that indicates all the penalties
    applied to a distance object.
    """
    penalties = []
    for key in distance.keys():
        key = key.replace("album_", "")
        key = key.replace("track_", "")
        key = key.replace("_", " ")
        penalties.append(key)
    if penalties:
        if limit and len(penalties) > limit:
            penalties = penalties[:limit] + ["..."]
        return ui.colorize("yellow", "(%s)" % ", ".join(penalties))
Example #50
0
def penalty_string(distance, limit=None):
    """Returns a colorized string that indicates all the penalties
    applied to a distance object.
    """
    penalties = []
    for key in distance.keys():
        key = key.replace('album_', '')
        key = key.replace('track_', '')
        key = key.replace('_', ' ')
        penalties.append(key)
    if penalties:
        if limit and len(penalties) > limit:
            penalties = penalties[:limit] + ['...']
        return ui.colorize('yellow', '(%s)' % ', '.join(penalties))
Example #51
0
def penalty_string(distance, limit=None):
    """Returns a colorized string that indicates all the penalties
    applied to a distance object.
    """
    penalties = []
    for key in distance.keys():
        key = key.replace('album_', '')
        key = key.replace('track_', '')
        key = key.replace('_', ' ')
        penalties.append(key)
    if penalties:
        if limit and len(penalties) > limit:
            penalties = penalties[:limit] + ['...']
        return ui.colorize('yellow', '(%s)' % ', '.join(penalties))
Example #52
0
    def show_album(artist, album, partial=False):
        if artist:
            album_description = u'    %s - %s' % (artist, album)
        elif album:
            album_description = u'    %s' % album
        else:
            album_description = u'    (unknown album)'

        out = album_description

        # Add a suffix if this is a partial match.
        if partial:
            out += u' ' + ui.colorize('yellow', PARTIAL_MATCH_MESSAGE)

        print_(out)
Example #53
0
    def show_album(artist, album, partial=False):
        if artist:
            album_description = u'    %s - %s' % (artist, album)
        elif album:
            album_description = u'    %s' % album
        else:
            album_description = u'    (unknown album)'

        out = album_description

        # Add a suffix if this is a partial match.
        if partial:
            out += u' %s' % ui.colorize('yellow', PARTIAL_MATCH_MESSAGE)

        print_(out)
Example #54
0
    def _play_command(self, lib, opts, args):
        """The CLI command function for `beet play`. Create a list of paths
        from query, determine if tracks or albums are to be played.
        """
        use_folders = config['play']['use_folders'].get(bool)
        relative_to = config['play']['relative_to'].get()
        if relative_to:
            relative_to = util.normpath(relative_to)
        # Perform search by album and add folders rather than tracks to
        # playlist.
        if opts.album:
            selection = lib.albums(ui.decargs(args))
            paths = []

            sort = lib.get_default_album_sort()
            for album in selection:
                if use_folders:
                    paths.append(album.item_dir())
                else:
                    paths.extend(item.path
                                 for item in sort.sort(album.items()))
            item_type = 'album'

        # Perform item query and add tracks to playlist.
        else:
            selection = lib.items(ui.decargs(args))
            paths = [item.path for item in selection]
            item_type = 'track'

        if relative_to:
            paths = [relpath(path, relative_to) for path in paths]

        if not selection:
            ui.print_(
                ui.colorize('text_warning',
                            u'No {0} to play.'.format(item_type)))
            return

        open_args = self._playlist_or_paths(paths)
        command_str = self._command_str(opts.args)

        # Check if the selection exceeds configured threshold. If True,
        # cancel, otherwise proceed with play command.
        if opts.yes or not self._exceeds_threshold(selection, command_str,
                                                   open_args, item_type):
            play(command_str, selection, paths, open_args, self._log,
                 item_type)
Example #55
0
File: play.py Project: arogl/beets
    def _play_command(self, lib, opts, args):
        """The CLI command function for `beet play`. Create a list of paths
        from query, determine if tracks or albums are to be played.
        """
        use_folders = config['play']['use_folders'].get(bool)
        relative_to = config['play']['relative_to'].get()
        if relative_to:
            relative_to = util.normpath(relative_to)
        # Perform search by album and add folders rather than tracks to
        # playlist.
        if opts.album:
            selection = lib.albums(ui.decargs(args))
            paths = []

            sort = lib.get_default_album_sort()
            for album in selection:
                if use_folders:
                    paths.append(album.item_dir())
                else:
                    paths.extend(item.path
                                 for item in sort.sort(album.items()))
            item_type = 'album'

        # Perform item query and add tracks to playlist.
        else:
            selection = lib.items(ui.decargs(args))
            paths = [item.path for item in selection]
            item_type = 'track'

        if relative_to:
            paths = [relpath(path, relative_to) for path in paths]

        if not selection:
            ui.print_(ui.colorize('text_warning',
                                  u'No {0} to play.'.format(item_type)))
            return

        open_args = self._playlist_or_paths(paths)
        command_str = self._command_str(opts.args)

        # Check if the selection exceeds configured threshold. If True,
        # cancel, otherwise proceed with play command.
        if opts.yes or not self._exceeds_threshold(
                selection, command_str, open_args, item_type):
            play(command_str, selection, paths, open_args, self._log,
                 item_type)
Example #56
0
    def show_album(artist, album, partial=False):
        if artist:
            album_description = u'    %s - %s' % (artist, album)
        elif album:
            album_description = u'    %s' % album
        else:
            album_description = u'    (unknown album)'

        # Add a suffix if this is a partial match.
        if partial:
            warning = PARTIAL_MATCH_MESSAGE
        else:
            warning = None
        if color and warning:
            warning = ui.colorize('yellow', warning)

        out = album_description
        if warning:
            out += u' ' + warning
        print_(out)
Example #57
0
    def album_distance(self, items, album_info, mapping):
        dist = hooks.Distance()

        # Add a penalty if these items have a barcode, but the album_id
        # does not correspond to the barcode(s).
        paths = set(map(lambda item: os.path.dirname(item.path), items))
        release_ids = set()
        for path in paths:
            if path in _matches:
                release_ids.update(_matches[path].album_ids)

        # Penalty only if we actually found barcodes for this path,
        # to avoid penalizing all relases if we haven't found any barcodes.
        if len(release_ids) != 0:
            dist.add_expr('barcode', album_info.album_id not in release_ids)
            if album_info.album_id in release_ids:
                album_info.data_source += '+' + ui.colorize(
                    'text_success', 'barcode')

        return dist
Example #58
0
    def on_import_task_before_choice(self, task, session):
        if hasattr(task, '_badfiles_checks_failed'):
            ui.print_('{} one or more files failed checks:'.format(
                ui.colorize('text_warning', 'BAD')))
            for error in task._badfiles_checks_failed:
                for error_line in error:
                    ui.print_(error_line)

            ui.print_()
            ui.print_('What would you like to do?')

            sel = ui.input_options(['aBort', 'skip', 'continue'])

            if sel == 's':
                return importer.action.SKIP
            elif sel == 'c':
                return None
            elif sel == 'b':
                raise importer.ImportAbort()
            else:
                raise Exception('Unexpected selection: {}'.format(sel))