コード例 #1
0
ファイル: duplicates.py プロジェクト: adamjakab/Beets
 def _process_item(self,
                   item,
                   copy=False,
                   move=False,
                   delete=False,
                   tag=False,
                   fmt=''):
     """Process Item `item`.
     """
     print_(format(item, fmt))
     if copy:
         item.move(basedir=copy, operation=MoveOperation.COPY)
         item.store()
     if move:
         item.move(basedir=move)
         item.store()
     if delete:
         item.remove(delete=True)
     if tag:
         try:
             k, v = tag.split('=')
         except Exception:
             raise UserError(f"{PLUGIN}: can't parse k=v tag: {tag}")
         setattr(item, k, v)
         item.store()
コード例 #2
0
ファイル: echonest.py プロジェクト: ykumar6/beets
def similar(lib, src_item, threshold=0.15, fmt='${difference}: ${path}'):
    for item in lib.items():
        if item.path != src_item.path:
            d = diff(item, src_item)
            if d < threshold:
                s = fmt.replace('${difference}', '{:2.2f}'.format(d))
                ui.print_(format(item, s))
コード例 #3
0
ファイル: missing.py プロジェクト: scztt/beets
        def _miss(lib, opts, args):
            self.config.set_args(opts)
            fmt = self.config['format'].get()
            count = self.config['count'].get()
            total = self.config['total'].get()

            albums = lib.albums(decargs(args))
            if total:
                print(sum([_missing_count(a) for a in albums]))
                return

            # Default format string for count mode.
            if count and not fmt:
                fmt = '$albumartist - $album: $missing'
                print fmt

            for album in albums:
                if count:
                    if _missing_count(album):
                        print_(format(album, fmt))

                else:
                    for (is_found, item) in _missing(album):
                        if is_found: sys.stdout.write('+ ')
                        else: sys.stdout.write('- ')
                        print_obj(item, lib)
コード例 #4
0
ファイル: commands.py プロジェクト: encukou/beets
def show_stats(lib, query):
    """Shows some statistics about the matched items."""
    items = lib.items(query)

    total_size = 0
    total_time = 0.0
    total_items = 0
    artists = set()
    albums = set()

    for item in items:
        #fixme This is approximate, so people might complain that
        # this total size doesn't match "du -sh". Could fix this
        # by putting total file size in the database.
        total_size += int(item.length * item.bitrate / 8)
        total_time += item.length
        total_items += 1
        artists.add(item.artist)
        albums.add(item.album)

    print_("""Tracks: %i
Total time: %s
Total size: %s
Artists: %i
Albums: %i""" % (
        total_items,
        ui.human_seconds(total_time),
        ui.human_bytes(total_size),
        len(artists), len(albums)
    ))
コード例 #5
0
 def _process_item(self,
                   item,
                   copy=False,
                   move=False,
                   delete=False,
                   tag=False,
                   fmt=u''):
     """Process Item `item`.
     """
     print_(format(item, fmt))
     if copy:
         item.move(basedir=copy, copy=True)
         item.store()
     if move:
         item.move(basedir=move, copy=False)
         item.store()
     if delete:
         item.remove(delete=True)
     if tag:
         try:
             k, v = tag.split('=')
         except Exception:
             raise UserError(u"{}: can't parse k=v tag: {}".format(
                 PLUGIN, tag))
         setattr(item, k, v)
         item.store()
コード例 #6
0
ファイル: info.py プロジェクト: triplem/beets
def info(paths):
    # Set up fields to output.
    fields = []
    for name, _, _, mffield in library.ITEM_FIELDS:
        if mffield:
            fields.append(name)

    # Line format.
    other_fields = ['album art']
    maxwidth = max(len(name) for name in fields + other_fields)
    lineformat = u'{{0:>{0}}}: {{1}}'.format(maxwidth)

    first = True
    for path in paths:
        if not first:
            ui.print_()

        path = util.normpath(path)
        ui.print_(path)
        try:
            mf = mediafile.MediaFile(path)
        except mediafile.UnreadableFileError:
            ui.print_('cannot read file')
            continue

        # Basic fields.
        for name in fields:
            ui.print_(lineformat.format(name, getattr(mf, name)))
        # Extra stuff.
        ui.print_(lineformat.format('album art', mf.art is not None))

        first = False
コード例 #7
0
ファイル: commands.py プロジェクト: mdecker/beets
def choose_item(task, config):
    """Ask the user for a choice about tagging a single item. Returns
    either an action constant or a track info dictionary.
    """
    print_()
    print_(task.item.path)
    candidates, rec = task.item_match

    if config.quiet:
        # Quiet mode; make a decision.
        if task.rec == autotag.RECOMMEND_STRONG:
            dist, track_info = candidates[0]
            show_item_change(task.item.color)
            return track_info
        else:
            return _quiet_fall_back(config)

    while True:
        # Ask for a choice.
        choice = choose_candidate(candidates, True, rec, config.color,
                                  config.interactive_autotag, item=task.item)

        if choice in (importer.action.SKIP, importer.action.ASIS):
            return choice
        elif choice == importer.action.TRACKS:
            assert False # TRACKS is only legal for albums.
        elif choice == importer.action.MANUAL:
            # Continue in the loop with a new set of candidates.
            search_artist, search_title = manual_search(False)
            candidates, rec = autotag.tag_item(task.item, search_artist,
                                               search_title)
        else:
            # Chose a candidate.
            assert not isinstance(choice, importer.action)
            return choice
コード例 #8
0
 def album_func(self, albums, opts):
   tagged_item_count = 0
   tagged_album_count = 0
   for album in albums:
     self.albumartist = None
     self.should_set = opts.reset
     
     if not opts.reset or not opts.quiet:
       for item in album.items():
         if 'vt_albumartist' in item:
           if self.albumartist is None:
             self.albumartist = item['vt_albumartist']
           elif self.albumartist != item['vt_albumartist']:
             self.albumartist = ""
         else:
           self.should_set = True
     else:
       self.albumartist = album.albumartist
     
     if not self.should_set:
       continue
     
     if not opts.quiet:
       fmt = u'    $albumartist - $album'
       self.process_item(album, fmt)
     for item in album.items():
       tagged_item_count += self.try_sync(item)
     tagged_album_count += 1
   ui.print_()
   ui.print_(u'Changed {} item(s) in {} album(s)'.format(tagged_item_count, tagged_album_count))
コード例 #9
0
ファイル: gmusic.py プロジェクト: arogl/beets
 def upload(self, lib, opts, args):
     items = lib.items(ui.decargs(args))
     files = self.getpaths(items)
     self.authenticate()
     ui.print_(u'Uploading your files...')
     self.m.upload(filepaths=files)
     ui.print_(u'Your files were successfully added to library')
コード例 #10
0
    def update(self, create=None):
        if not os.path.isdir(self.directory) and not self.ask_create(create):
            print_(u'Skipping creation of {0}'
                   .format(displayable_path(self.directory)))
            return

        converter = self.converter()
        for (item, action) in self.items_action():
            dest = self.destination(item)
            path = self.get_path(item)
            if action == self.MOVE:
                print_(u'>{0} -> {1}'.format(displayable_path(path),
                                             displayable_path(dest)))
                util.mkdirall(dest)
                util.move(path, dest)
                util.prune_dirs(os.path.dirname(path), root=self.directory)
                self.set_path(item, dest)
                item.store()
                item.write(path=dest)
            elif action == self.WRITE:
                print_(u'*{0}'.format(displayable_path(path)))
                item.write(path=path)
            elif action == self.ADD:
                print_(u'+{0}'.format(displayable_path(dest)))
                converter.submit(item)
            elif action == self.REMOVE:
                print_(u'-{0}'.format(displayable_path(path)))
                self.remove_item(item)
                item.store()

        for item, dest in converter.as_completed():
            self.set_path(item, dest)
            item.store()
        converter.shutdown()
コード例 #11
0
ファイル: __init__.py プロジェクト: Lugoues/beets-lyrics
    def album_imported(self, lib, album):
        if self.on_import == False :
            pass

        print_("Tagging Lyrics:  %s - %s" % (album.albumartist, album.album))

        def fetch(item, artist, title):
            try:
                #print_("    -%s:" % (title), ui.colorize('yellow', 'Fetching'))
                lyrics = self.fetchLyrics(scrub(artist), scrub(title))
                return (item, lyrics)
            except:
                return None
                
        def tag( item, lyrics):
            try:
                #print_("    -%s:" % (item.title), ui.colorize('green', 'Updated!'))
                item.lyrics = lyrics
                item.write()
                lib.store(item)
            except:
                pass
                
        [(item, item.artist, item.title) for item in album.items()]  \
            >> ThreadPool(apply(fetch), poolsize=self.processcount)  \
            >> filter( lambda itm: itm != None) \
            >> ThreadPool(apply(tag), poolsize=1)
コード例 #12
0
ファイル: commands.py プロジェクト: jlefley/beets
def _summary_judment(rec):
    """Determines whether a decision should be made without even asking
    the user. This occurs in quiet mode and when an action is chosen for
    NONE recommendations. Return an action or None if the user should be
    queried. May also print to the console if a summary judgment is
    made.
    """
    if config['import']['quiet']:
        if rec == recommendation.strong:
            return importer.action.APPLY
        else:
            action = config['import']['quiet_fallback'].as_choice({
                'skip': importer.action.SKIP,
                'asis': importer.action.ASIS,
            })

    elif rec == recommendation.none:
        action = config['import']['none_rec_action'].as_choice({
            'skip': importer.action.SKIP,
            'asis': importer.action.ASIS,
            'ask': None,
        })

    else:
        return None

    if action == importer.action.SKIP:
        print_('Skipping.')
    elif action == importer.action.ASIS:
        print_('Importing as-is.')
    return action
コード例 #13
0
    def command(self, lib, opts, args):
        self.config.set_args(opts)
        self.set_fields()

        query = decargs(args)
        for album in lib.albums(query):
            inconsistent_fields = defaultdict(list)
            album_items = album.items()

            for item in album_items:
                for field in self.included_fields:
                    if item[field] != album[field]:
                        inconsistent_fields[field].append(item)

            for field in sorted(inconsistent_fields):
                items = inconsistent_fields[field]
                if len(items) == len(album_items):
                    print_(
                        u'{}: field `{}` has album value `{}` but all track values are `{}`'
                        .format(album, field, album[field], items[0][field]))
                else:
                    for item in items:
                        print_(
                            u'{}: field `{}` has value `{}` but album value is `{}`'
                            .format(item, field, item[field], album[field]))
コード例 #14
0
ファイル: commands.py プロジェクト: encukou/beets
def remove_items(lib, query, album, delete=False):
    """Remove items matching query from lib. If album, then match and
    remove whole albums. If delete, also remove files from disk.
    """
    # Get the matching items.
    items, albums = _do_query(lib, query, album)

    # Show all the items.
    for item in items:
        print_(item.artist + ' - ' + item.album + ' - ' + item.title)

    # Confirm with user.
    print_()
    if delete:
        prompt = 'Really DELETE %i files (y/n)?' % len(items)
    else:
        prompt = 'Really remove %i items from the library (y/n)?' % \
                 len(items)
    if not ui.input_yn(prompt, True):
        return

    # Remove (and possibly delete) items.
    with lib.transaction():
        if album:
            for al in albums:
                al.remove(delete)
        else:
            for item in items:
                lib.remove(item, delete)
コード例 #15
0
ファイル: gmusic.py プロジェクト: maffo999/beets
 def upload(self, lib, opts, args):
     items = lib.items(ui.decargs(args))
     files = self.getpaths(items)
     self.authenticate()
     ui.print_('Uploading your files...')
     self.m.upload(filepaths=files)
     ui.print_('Your files were successfully added to library')
コード例 #16
0
ファイル: gmusic.py プロジェクト: SerhatG/nzbToMedia
 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')
コード例 #17
0
ファイル: __init__.py プロジェクト: vitalybe/beets
    def preview_playlist_command(self, lib, opts, args):
        name_column_length = 60
        count = 10

        self._log.info(config.user_config_path())

        if opts.count:
            count = int(opts.count)

        if opts.playlist:
            if opts.playlist not in _settings.playlists:
                self._log.error(u'Playlist not defined: {}'.format(opts.playlist))
                return
            query = _settings.playlists[opts.playlist].query.split(u" ")
        else:
            query = decargs(args)

        query = u" ".join(query)
        query = ignore_deleted_in_query(query)
        items = playlist_generator.generate_playlist(lib, _settings.rules, count, opts.shuffle, query)

        for item in items:
            score_string = ", ".join(['%s: %s' % (key.replace("rule_", ""), value) for (key, value) in sorted(item.scores.items())])
            score_sum = round(sum(item.scores.values()), 2)
            item_name = unicode(item)
            if len(item_name) > name_column_length-5:
                item_name = item_name[:name_column_length-5] + "..."
            item_string = item_name.ljust(name_column_length)
            print_(u"Track: {0} Scores: {1}=[{2}]".format(item_string, score_sum, score_string))
コード例 #18
0
    def convert_func(self, lib, opts, args):
        dest = opts.dest or self.config['dest'].get()
        if not dest:
            raise ui.UserError(u'no convert destination set')
        dest = util.bytestring_path(dest)

        threads = opts.threads or self.config['threads'].get(int)

        path_formats = ui.get_path_formats(self.config['paths'] or None)

        fmt = opts.format or self.config['format'].as_str().lower()

        if opts.pretend is not None:
            pretend = opts.pretend
        else:
            pretend = self.config['pretend'].get(bool)

        if opts.hardlink is not None:
            hardlink = opts.hardlink
            link = False
        elif opts.link is not None:
            hardlink = False
            link = opts.link
        else:
            hardlink = self.config['hardlink'].get(bool)
            link = self.config['link'].get(bool)

        if opts.album:
            albums = lib.albums(ui.decargs(args))
            items = [i for a in albums for i in a.items()]
            if not pretend:
                for a in albums:
                    ui.print_(format(a, u''))
        else:
            items = list(lib.items(ui.decargs(args)))
            if not pretend:
                for i in items:
                    ui.print_(format(i, u''))

        if not items:
            self._log.error(u'Empty query result.')
            return
        if not (pretend or opts.yes or ui.input_yn(u"Convert? (Y/n)")):
            return

        if opts.album and self.config['copy_album_art']:
            for album in albums:
                self.copy_album_art(album, dest, path_formats, pretend,
                                    link, hardlink)

        convert = [self.convert_item(dest,
                                     opts.keep_new,
                                     path_formats,
                                     fmt,
                                     pretend,
                                     link,
                                     hardlink)
                   for _ in range(threads)]
        pipe = util.pipeline.Pipeline([iter(items), convert])
        pipe.run_parallel()
コード例 #19
0
ファイル: duplicates.py プロジェクト: skumar225/beets
def _process_item(item,
                  lib,
                  copy=False,
                  move=False,
                  delete=False,
                  tag=False,
                  format=''):
    """Process Item `item` in `lib`.
    """
    if copy:
        item.move(basedir=copy, copy=True)
        item.store()
    if move:
        item.move(basedir=move, copy=False)
        item.store()
    if delete:
        item.remove(delete=True)
    if tag:
        try:
            k, v = tag.split('=')
        except:
            raise UserError('%s: can\'t parse k=v tag: %s' % (PLUGIN, tag))
        setattr(k, v)
        item.store()
    print_(format(item, format))
コード例 #20
0
    def update(self, create=None):
        if not os.path.isdir(self.directory) and not self.ask_create(create):
            print_(u'Skipping creation of {0}'.format(
                displayable_path(self.directory)))
            return

        converter = self.converter()
        for (item, action) in self.items_action():
            dest = self.destination(item)
            path = self.get_path(item)
            if action == self.MOVE:
                print_(u'>{0} -> {1}'.format(displayable_path(path),
                                             displayable_path(dest)))
                util.mkdirall(dest)
                util.move(path, dest)
                util.prune_dirs(os.path.dirname(path), root=self.directory)
                self.set_path(item, dest)
                item.store()
                item.write(path=dest)
            elif action == self.WRITE:
                print_(u'*{0}'.format(displayable_path(path)))
                item.write(path=path)
            elif action == self.ADD:
                print_(u'+{0}'.format(displayable_path(dest)))
                converter.submit(item)
            elif action == self.REMOVE:
                print_(u'-{0}'.format(displayable_path(path)))
                self.remove_item(item)
                item.store()

        for item, dest in converter.as_completed():
            self.set_path(item, dest)
            item.store()
        converter.shutdown()
コード例 #21
0
ファイル: commands.py プロジェクト: silky/beets
def remove_items(lib, query, album, delete):
    """Remove items matching query from lib. If album, then match and
    remove whole albums. If delete, also remove files from disk.
    """
    # Get the matching items.
    items, albums = _do_query(lib, query, album)

    # Show all the items.
    for item in items:
        ui.print_obj(item, lib)

    # Confirm with user.
    print_()
    if delete:
        prompt = 'Really DELETE %i files (y/n)?' % len(items)
    else:
        prompt = 'Really remove %i items from the library (y/n)?' % \
                 len(items)
    if not ui.input_yn(prompt, True):
        return

    # Remove (and possibly delete) items.
    with lib.transaction():
        for obj in (albums if album else items):
            obj.remove(delete)
コード例 #22
0
def remove_items(lib, query, album, delete=False):
    """Remove items matching query from lib. If album, then match and
    remove whole albums. If delete, also remove files from disk.
    """
    # Get the matching items.
    items, albums = _do_query(lib, query, album)

    # Show all the items.
    for item in items:
        print_(item.artist + ' - ' + item.album + ' - ' + item.title)

    # Confirm with user.
    print_()
    if delete:
        prompt = 'Really DELETE %i files (y/n)?' % len(items)
    else:
        prompt = 'Really remove %i items from the library (y/n)?' % \
                 len(items)
    if not ui.input_yn(prompt, True):
        return

    # Remove (and possibly delete) items.
    if album:
        for al in albums:
            al.remove(delete)
    else:
        for item in items:
            lib.remove(item, delete)

    lib.save()
コード例 #23
0
ファイル: commands.py プロジェクト: breunigs/beets
def _summary_judment(rec):
    """Determines whether a decision should be made without even asking
    the user. This occurs in quiet mode and when an action is chosen for
    NONE recommendations. Return an action or None if the user should be
    queried. May also print to the console if a summary judgment is
    made.
    """
    if config['import']['quiet']:
        if rec == recommendation.strong:
            return importer.action.APPLY
        else:
            action = config['import']['quiet_fallback'].as_choice({
                'skip': importer.action.SKIP,
                'asis': importer.action.ASIS,
            })

    elif rec == recommendation.none:
        action = config['import']['none_rec_action'].as_choice({
            'skip': importer.action.SKIP,
            'asis': importer.action.ASIS,
            'ask': None,
        })

    else:
        return None

    if action == importer.action.SKIP:
        print_('Skipping.')
    elif action == importer.action.ASIS:
        print_('Importing as-is.')
    return action
コード例 #24
0
ファイル: smartplaylist.py プロジェクト: subrams1/beets
def update_playlists(lib):
    ui.print_("Updating smart playlists...")
    playlists = config['smartplaylist']['playlists'].get(list)
    playlist_dir = config['smartplaylist']['playlist_dir'].as_filename()
    relative_to = config['smartplaylist']['relative_to'].get()
    if relative_to:
        relative_to = normpath(relative_to)

    for playlist in playlists:
        items = []
        items.extend(_items_for_query(lib, playlist, True))
        items.extend(_items_for_query(lib, playlist, False))

        m3us = {}
        basename = playlist['name'].encode('utf8')
        # As we allow tags in the m3u names, we'll need to iterate through
        # the items and generate the correct m3u file names.
        for item in items:
            m3u_name = item.evaluate_template(basename, True)
            if not (m3u_name in m3us):
                m3us[m3u_name] = []
            item_path = item.path
            if relative_to:
                item_path = os.path.relpath(item.path, relative_to)
            if item_path not in m3us[m3u_name]:
                m3us[m3u_name].append(item_path)
        # Now iterate through the m3us that we need to generate
        for m3u in m3us:
            m3u_path = normpath(os.path.join(playlist_dir, m3u))
            with open(syspath(m3u_path), 'w') as f:
                for path in m3us[m3u]:
                    f.write(path + '\n')
    ui.print_("... Done")
コード例 #25
0
def show_stats(lib, query):
    """Shows some statistics about the matched items."""
    items = lib.items(query)

    total_size = 0
    total_time = 0.0
    total_items = 0
    artists = set()
    albums = set()

    for item in items:
        #fixme This is approximate, so people might complain that
        # this total size doesn't match "du -sh". Could fix this
        # by putting total file size in the database.
        total_size += int(item.length * item.bitrate / 8)
        total_time += item.length
        total_items += 1
        artists.add(item.artist)
        albums.add(item.album)

    print_("""Tracks: %i
Total time: %s
Total size: %s
Artists: %i
Albums: %i""" % (total_items, ui.human_seconds(total_time),
                 ui.human_bytes(total_size), len(artists), len(albums)))
コード例 #26
0
ファイル: missing.py プロジェクト: JDLH/beets
    def _missing_tracks(self, lib, query):
        """Print a listing of tracks missing from each album in the library
        matching query.
        """
        albums = lib.albums(query)

        count = self.config['count'].get()
        total = self.config['total'].get()
        fmt = config['format_album' if count else 'format_item'].get()

        if total:
            print(sum([_missing_count(a) for a in albums]))
            return

        # Default format string for count mode.
        if count:
            fmt += ': $missing'

        for album in albums:
            if count:
                if _missing_count(album):
                    print_(format(album, fmt))

            else:
                for item in self._missing(album):
                    print_(format(item, fmt))
コード例 #27
0
ファイル: commands.py プロジェクト: Tantali/beets
def modify_items(lib, mods, query, write, move, album, confirm):
    """Modifies matching items according to key=value assignments."""
    # Parse key=value specifications into a dictionary.
    if album:
        allowed_keys = library.ALBUM_KEYS
    else:
        allowed_keys = library.ITEM_KEYS_WRITABLE + ['added']
    fsets = {}
    for mod in mods:
        key, value = mod.split('=', 1)
        if key not in allowed_keys:
            raise ui.UserError('"%s" is not a valid field' % key)
        fsets[key] = _convert_type(key, value, album)

    # Get the items to modify.
    items, albums = _do_query(lib, query, album, False)
    objs = albums if album else items

    # Preview change.
    print_('Modifying %i %ss.' % (len(objs), 'album' if album else 'item'))
    for obj in objs:
        # Identify the changed object.
        ui.print_obj(obj, lib)

        # Show each change.
        for field, value in fsets.iteritems():
            curval = getattr(obj, field)
            _showdiff(field, curval, value)

    # Confirm.
    if confirm:
        extra = ' and write tags' if write else ''
        if not ui.input_yn('Really modify%s (Y/n)?' % extra):
            return

    # Apply changes to database.
    with lib.transaction():
        for obj in objs:
            for field, value in fsets.iteritems():
                setattr(obj, field, value)

            if move:
                cur_path = obj.item_dir() if album else obj.path
                if lib.directory in ancestry(cur_path): # In library?
                    log.debug('moving object %s' % cur_path)
                    if album:
                        obj.move()
                    else:
                        lib.move(obj)

            # When modifying items, we have to store them to the database.
            if not album:
                lib.store(obj)

    # Apply tags if requested.
    if write:
        if album:
            items = itertools.chain(*(a.items() for a in albums))
        for item in items:
            item.write()
コード例 #28
0
def show_stats(lib, query, exact):
    """Shows some statistics about the matched items."""
    items = lib.items(query)

    total_size = 0
    total_time = 0.0
    total_items = 0
    artists = set()
    albums = set()

    for item in items:
        if exact:
            total_size += os.path.getsize(item.path)
        else:
            total_size += int(item.length * item.bitrate / 8)
        total_time += item.length
        total_items += 1
        artists.add(item.artist)
        albums.add(item.album)

    size_str = '' + ui.human_bytes(total_size)
    if exact:
        size_str += ' ({0} bytes)'.format(total_size)

    print_("""Tracks: {0}
Total time: {1} ({2:.2f} seconds)
Total size: {3}
Artists: {4}
Albums: {5}""".format(total_items, ui.human_seconds(total_time), total_time,
                      size_str, len(artists), len(albums)))
コード例 #29
0
def modify_items(lib, mods, query, write, move, album, confirm):
    """Modifies matching items according to key=value assignments."""
    # Parse key=value specifications into a dictionary.
    if album:
        allowed_keys = library.ALBUM_KEYS
    else:
        allowed_keys = library.ITEM_KEYS_WRITABLE + ['added']
    fsets = {}
    for mod in mods:
        key, value = mod.split('=', 1)
        if key not in allowed_keys:
            raise ui.UserError('"%s" is not a valid field' % key)
        fsets[key] = _convert_type(key, value, album)

    # Get the items to modify.
    items, albums = _do_query(lib, query, album, False)
    objs = albums if album else items

    # Preview change.
    print_('Modifying %i %ss.' % (len(objs), 'album' if album else 'item'))
    for obj in objs:
        # Identify the changed object.
        ui.print_obj(obj, lib)

        # Show each change.
        for field, value in fsets.iteritems():
            curval = getattr(obj, field)
            _showdiff(field, curval, value)

    # Confirm.
    if confirm:
        extra = ' and write tags' if write else ''
        if not ui.input_yn('Really modify%s (Y/n)?' % extra):
            return

    # Apply changes to database.
    with lib.transaction():
        for obj in objs:
            for field, value in fsets.iteritems():
                setattr(obj, field, value)

            if move:
                cur_path = obj.item_dir() if album else obj.path
                if lib.directory in ancestry(cur_path):  # In library?
                    log.debug('moving object %s' % cur_path)
                    if album:
                        obj.move()
                    else:
                        lib.move(obj)

            # When modifying items, we have to store them to the database.
            if not album:
                lib.store(obj)

    # Apply tags if requested.
    if write:
        if album:
            items = itertools.chain(*(a.items() for a in albums))
        for item in items:
            item.write()
コード例 #30
0
ファイル: smartplaylist.py プロジェクト: 241n/beets
def update_playlists(lib):
    ui.print_("Updating smart playlists...")
    playlists = config['smartplaylist']['playlists'].get(list)
    playlist_dir = config['smartplaylist']['playlist_dir'].as_filename()
    relative_to = config['smartplaylist']['relative_to'].get()
    if relative_to:
        relative_to = normpath(relative_to)

    for playlist in playlists:
        items = []
        items.extend(_items_for_query(lib, playlist, True))
        items.extend(_items_for_query(lib, playlist, False))

        m3us = {}
        basename = playlist['name'].encode('utf8')
        # As we allow tags in the m3u names, we'll need to iterate through
        # the items and generate the correct m3u file names.
        for item in items:
            m3u_name = item.evaluate_template(basename, True)
            if not (m3u_name in m3us):
                m3us[m3u_name] = []
            item_path = item.path
            if relative_to:
                item_path = os.path.relpath(item.path, relative_to)
            if item_path not in m3us[m3u_name]:
                m3us[m3u_name].append(item_path)
        # Now iterate through the m3us that we need to generate
        for m3u in m3us:
            m3u_path = normpath(os.path.join(playlist_dir, m3u))
            with open(syspath(m3u_path), 'w') as f:
                for path in m3us[m3u]:
                    f.write(path + '\n')
    ui.print_("... Done")
コード例 #31
0
ファイル: gmusic.py プロジェクト: RobbeeUA/Music
 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')
コード例 #32
0
ファイル: commands.py プロジェクト: jlefley/beets
def remove_items(lib, query, album, delete):
    """Remove items matching query from lib. If album, then match and
    remove whole albums. If delete, also remove files from disk.
    """
    # Get the matching items.
    items, albums = _do_query(lib, query, album)

    # Show all the items.
    for item in items:
        ui.print_obj(item, lib)

    # Confirm with user.
    print_()
    if delete:
        prompt = 'Really DELETE %i files (y/n)?' % len(items)
    else:
        prompt = 'Really remove %i items from the library (y/n)?' % \
                 len(items)
    if not ui.input_yn(prompt, True):
        return

    # Remove (and possibly delete) items.
    with lib.transaction():
        for obj in (albums if album else items):
            obj.remove(delete)
コード例 #33
0
ファイル: open.py プロジェクト: kergoth/beets-kergoth
    def open(self, lib, opts, args):
        query = ui.decargs(args)

        if opts.album:
            items = lib.albums(query)
        else:
            items = lib.items(query)

        if not items:
            raise ui.UserError("nothing to open")

        cmd = util.open_anything()
        if opts.args:
            cmd += " " + opts.args
        paths = [item.path for item in items]
        if opts.reveal:
            paths = [os.path.dirname(p) for p in paths]
        self._log.debug("invoking command: {} {}", cmd,
                        subprocess.list2cmdline(paths))

        item_type = "album" if opts.album else "track"
        item_type += "s" if len(items) > 1 else ""
        if opts.reveal:
            action = "Revealing"
        else:
            action = "Opening"
        ui.print_("{} {} {}.".format(action, len(items), item_type))

        try:
            util.interactive_open(paths, cmd)
        except OSError as exc:
            raise ui.UserError("failed to invoke {}: {}".format(cmd, exc))
コード例 #34
0
ファイル: info.py プロジェクト: nidico/beets
def info(paths):
    # Set up fields to output.
    fields = []
    for name, _, _, mffield in library.ITEM_FIELDS:
        if mffield:
            fields.append(name)

    # Line format.
    other_fields = ['album art']
    maxwidth = max(len(name) for name in fields + other_fields)
    lineformat = u'{{:>{0}}}: {{0}}'.format(maxwidth)

    first = True
    for path in paths:
        if not first:
            ui.print_()

        path = util.normpath(path)
        ui.print_(path)
        try:
            mf = mediafile.MediaFile(path)
        except mediafile.UnreadableFileError:
            ui.print_('cannot read file')
            continue

        # Basic fields.
        for name in fields:
            ui.print_(lineformat.format(name, getattr(mf, name)))
        # Extra stuff.
        ui.print_(lineformat.format('album art', mf.art is not None))


        first = False
コード例 #35
0
    def _missing_tracks(self, lib, query):
        """Print a listing of tracks missing from each album in the library
        matching query.
        """
        albums = lib.albums(query)

        count = self.config['count'].get()
        total = self.config['total'].get()
        fmt = config['format_album' if count else 'format_item'].get()

        if total:
            print(sum([_missing_count(a) for a in albums]))
            return

        # Default format string for count mode.
        if count:
            fmt += ': $missing'

        for album in albums:
            if count:
                if _missing_count(album):
                    print_(format(album, fmt))

            else:
                for item in self._missing(album):
                    print_(format(item, fmt))
コード例 #36
0
ファイル: echonest.py プロジェクト: jck/beets
def similar(lib, src_item, threshold=0.15, fmt='${difference}: ${path}'):
    for item in lib.items():
        if item.path != src_item.path:
            d = diff(item, src_item)
            if d < threshold:
                s = fmt.replace('${difference}', '{:2.2f}'.format(d))
                ui.print_(format(item, s))
コード例 #37
0
ファイル: convert.py プロジェクト: aereaux/beets
    def convert_func(self, lib, opts, args):
        (dest, threads, path_formats, fmt, pretend, hardlink,
         link) = self._get_opts_and_config(opts)

        if opts.album:
            albums = lib.albums(ui.decargs(args))
            items = [i for a in albums for i in a.items()]
            if not pretend:
                for a in albums:
                    ui.print_(format(a, ''))
        else:
            items = list(lib.items(ui.decargs(args)))
            if not pretend:
                for i in items:
                    ui.print_(format(i, ''))

        if not items:
            self._log.error('Empty query result.')
            return
        if not (pretend or opts.yes or ui.input_yn("Convert? (Y/n)")):
            return

        if opts.album and self.config['copy_album_art']:
            for album in albums:
                self.copy_album_art(album, dest, path_formats, pretend, link,
                                    hardlink)

        self._parallel_convert(dest, opts.keep_new, path_formats, fmt, pretend,
                               link, hardlink, threads, items)
コード例 #38
0
 def func(lib, opts, args):
     # The "write to files" option corresponds to the
     # import_write config value.
     write = ui.should_write()
     if opts.writerest:
         self.writerest_indexes(opts.writerest)
     for item in lib.items(ui.decargs(args)):
         if not opts.local_only and not self.config['local']:
             self.fetch_item_lyrics(
                 lib,
                 item,
                 write,
                 opts.force_refetch or self.config['force'],
             )
         if item.lyrics:
             if opts.printlyr:
                 ui.print_(item.lyrics)
             if opts.writerest:
                 self.writerest(opts.writerest, item)
     if opts.writerest:
         # flush last artist
         self.writerest(opts.writerest, None)
         ui.print_(u'ReST files generated. to build, use one of:')
         ui.print_(u'  sphinx-build -b html %s _build/html' %
                   opts.writerest)
         ui.print_(u'  sphinx-build -b epub %s _build/epub' %
                   opts.writerest)
         ui.print_(
             (u'  sphinx-build -b latex %s _build/latex '
              u'&& make -C _build/latex all-pdf') % opts.writerest)
コード例 #39
0
ファイル: commands.py プロジェクト: simonwarwick/beets
def _summary_judment(rec):
    """Determines whether a decision should be made without even asking
    the user. This occurs in quiet mode and when an action is chosen for
    NONE recommendations. Return an action or None if the user should be
    queried. May also print to the console if a summary judgment is
    made.
    """
    if config["import"]["quiet"]:
        if rec == recommendation.strong:
            return importer.action.APPLY
        else:
            action = config["import"]["quiet_fallback"].as_choice(
                {"skip": importer.action.SKIP, "asis": importer.action.ASIS}
            )

    elif rec == recommendation.none:
        action = config["import"]["none_rec_action"].as_choice(
            {"skip": importer.action.SKIP, "asis": importer.action.ASIS, "ask": None}
        )

    else:
        return None

    if action == importer.action.SKIP:
        print_("Skipping.")
    elif action == importer.action.ASIS:
        print_("Importing as-is.")
    return action
コード例 #40
0
ファイル: lyrics.py プロジェクト: SerhatG/nzbToMedia
 def func(lib, opts, args):
     # The "write to files" option corresponds to the
     # import_write config value.
     write = ui.should_write()
     if opts.writerest:
         self.writerest_indexes(opts.writerest)
     for item in lib.items(ui.decargs(args)):
         if not opts.local_only and not self.config['local']:
             self.fetch_item_lyrics(
                 lib, item, write,
                 opts.force_refetch or self.config['force'],
             )
         if item.lyrics:
             if opts.printlyr:
                 ui.print_(item.lyrics)
             if opts.writerest:
                 self.writerest(opts.writerest, item)
     if opts.writerest:
         # flush last artist
         self.writerest(opts.writerest, None)
         ui.print_(u'ReST files generated. to build, use one of:')
         ui.print_(u'  sphinx-build -b html %s _build/html'
                   % opts.writerest)
         ui.print_(u'  sphinx-build -b epub %s _build/epub'
                   % opts.writerest)
         ui.print_((u'  sphinx-build -b latex %s _build/latex '
                    u'&& make -C _build/latex all-pdf')
                   % opts.writerest)
コード例 #41
0
ファイル: commands.py プロジェクト: imenem/beets
def show_stats(lib, query, exact):
    """Shows some statistics about the matched items."""
    items = lib.items(query)

    total_size = 0
    total_time = 0.0
    total_items = 0
    artists = set()
    albums = set()

    for item in items:
        if exact:
            total_size += os.path.getsize(item.path)
        else:
            total_size += int(item.length * item.bitrate / 8)
        total_time += item.length
        total_items += 1
        artists.add(item.artist)
        albums.add(item.album)

    size_str = '' + ui.human_bytes(total_size)
    if exact:
        size_str += ' ({0} bytes)'.format(total_size)

    print_("""Tracks: {0}
Total time: {1} ({2:.2f} seconds)
Total size: {3}
Artists: {4}
Albums: {5}""".format(total_items, ui.human_seconds(total_time), total_time,
                      size_str, len(artists), len(albums)))
コード例 #42
0
ファイル: commands.py プロジェクト: korozif/beets
def modify_items(lib, mods, query, write, move, album, confirm):
    """Modifies matching items according to key=value assignments."""
    # Parse key=value specifications into a dictionary.
    model_cls = library.Album if album else library.Item
    fsets = {}
    for mod in mods:
        key, value = mod.split('=', 1)
        fsets[key] = model_cls._parse(key, value)

    # Get the items to modify.
    items, albums = _do_query(lib, query, album, False)
    objs = albums if album else items

    # Preview change and collect modified objects.
    print_('Modifying %i %ss.' % (len(objs), 'album' if album else 'item'))
    changed = set()
    for obj in objs:
        # Identify the changed object.
        ui.print_obj(obj, lib)

        # Show each change.
        for field, value in fsets.iteritems():
            if _showdiff(field, obj._get_formatted(field),
                         obj._format(field, value)):
                changed.add(obj)

    # Still something to do?
    if not changed:
        print_('No changes to make.')
        return

    # Confirm action.
    if confirm:
        extra = ' and write tags' if write else ''
        if not ui.input_yn('Really modify%s (Y/n)?' % extra):
            return

    # Apply changes to database.
    with lib.transaction():
        for obj in changed:
            for field, value in fsets.iteritems():
                obj[field] = value

            if move:
                cur_path = obj.path
                if lib.directory in ancestry(cur_path): # In library?
                    log.debug('moving object %s' % cur_path)
                    obj.move()

            obj.store()

    # Apply tags if requested.
    if write:
        if album:
            changed_items = itertools.chain(*(a.items() for a in changed))
        else:
            changed_items = changed
        for item in changed_items:
            item.write()
コード例 #43
0
ファイル: lyrics.py プロジェクト: Kraymer/beets
 def func(lib, opts, args):
     # The "write to files" option corresponds to the
     # import_write config value.
     write = ui.should_write()
     for item in lib.items(ui.decargs(args)):
         self.fetch_item_lyrics(lib, item, write, opts.force_refetch or self.config["force"])
         if opts.printlyr and item.lyrics:
             ui.print_(item.lyrics)
コード例 #44
0
ファイル: commands.py プロジェクト: jlefley/beets
 def show_album(artist, album):
     if artist:
         album_description = u'    %s - %s' % (artist, album)
     elif album:
         album_description = u'    %s' % album
     else:
         album_description = u'    (unknown album)'
     print_(album_description)
コード例 #45
0
ファイル: lyrics.py プロジェクト: encukou/beets
 def func(lib, config, opts, args):
     # The "write to files" option corresponds to the
     # import_write config value.
     write = ui.config_val(config, "beets", "import_write", commands.DEFAULT_IMPORT_WRITE, bool)
     for item in lib.items(ui.decargs(args)):
         fetch_item_lyrics(lib, logging.INFO, item, write)
         if opts.printlyr and item.lyrics:
             ui.print_(item.lyrics)
コード例 #46
0
 def func(lib, opts, args):
     # The "write to files" option corresponds to the
     # import_write config value.
     write = config['import']['write'].get(bool)
     for item in lib.items(ui.decargs(args)):
         fetch_item_lyrics(lib, logging.INFO, item, write)
         if opts.printlyr and item.lyrics:
             ui.print_(item.lyrics)
コード例 #47
0
ファイル: commands.py プロジェクト: breunigs/beets
 def show_album(artist, album):
     if artist:
         album_description = u'    %s - %s' % (artist, album)
     elif album:
         album_description = u'    %s' % album
     else:
         album_description = u'    (unknown album)'
     print_(album_description)
コード例 #48
0
ファイル: lyrics.py プロジェクト: chriscogburn/beets
 def func(lib, opts, args):
     # The "write to files" option corresponds to the
     # import_write config value.
     write = config['import']['write'].get(bool)
     for item in lib.items(ui.decargs(args)):
         self.fetch_item_lyrics(lib, logging.INFO, item, write)
         if opts.printlyr and item.lyrics:
             ui.print_(item.lyrics)
コード例 #49
0
ファイル: advisory.py プロジェクト: kergoth/beets-kergoth
 def read_advisory(self, lib, opts, args):
     self.config.set_args(opts)
     query = decargs(args)
     items, _ = _do_query(lib, query, None, False)
     if not items:
         print_(u'No items matched the specified query: {0}.'.format(' '.join(query)))
         return
     self.read_items(lib, items, pretend=opts.pretend)
コード例 #50
0
ファイル: soletracks.py プロジェクト: kergoth/Beets-Library
    def list_command(self, lib, opts, args):
        self.handle_common_args(opts, args)

        for item, is_sole_track in self.list_sole_tracks(lib):
            if is_sole_track:
                ui.print_(format(item))
            elif opts.non_matching and not is_sole_track:
                ui.print_(format(item))
コード例 #51
0
ファイル: __init__.py プロジェクト: Lugoues/beets-lyrics
 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
コード例 #52
0
ファイル: commands.py プロジェクト: simonwarwick/beets
 def show_album(artist, album):
     if artist:
         album_description = u"    %s - %s" % (artist, album)
     elif album:
         album_description = u"    %s" % album
     else:
         album_description = u"    (unknown album)"
     print_(album_description)
コード例 #53
0
ファイル: commands.py プロジェクト: TinyHTPC/xbmc-dev-repo
def modify_items(lib, mods, dels, query, write, move, album, confirm):
    """Modifies matching items according to key=value assignments."""
    # Parse key=value specifications into a dictionary.
    model_cls = library.Album if album else library.Item
    fsets = {}
    for mod in mods:
        key, value = mod.split('=', 1)
        fsets[key] = model_cls._parse(key, value)

    # Get the items to modify.
    items, albums = _do_query(lib, query, album, False)
    objs = albums if album else items

    # Apply changes *temporarily*, preview them, and collect modified
    # objects.
    print_('Modifying %i %ss.' % (len(objs), 'album' if album else 'item'))
    changed = set()
    for obj in objs:
        for field, value in fsets.iteritems():
            obj[field] = value
        for field in dels:
            del obj[field]
        if ui.show_model_changes(obj):
            changed.add(obj)

    # Still something to do?
    if not changed:
        print_('No changes to make.')
        return

    # Confirm action.
    if confirm:
        extra = ' and write tags' if write else ''
        if not ui.input_yn('Really modify%s (Y/n)?' % extra):
            return

    # Apply changes to database.
    with lib.transaction():
        for obj in changed:
            if move:
                cur_path = obj.path
                if lib.directory in ancestry(cur_path): # In library?
                    log.debug('moving object %s' % cur_path)
                    obj.move()

            obj.store()

    # Apply tags if requested.
    if write:
        if album:
            changed_items = itertools.chain(*(a.items() for a in changed))
        else:
            changed_items = changed
        for item in changed_items:
            try:
                item.write()
            except library.FileOperationError as exc:
                log.error(exc)
コード例 #54
0
ファイル: commands.py プロジェクト: navinpai/beets
def update_items(lib, query, album, move, color):
    """For all the items matched by the query, update the library to
    reflect the item's embedded tags.
    """
    items, _ = _do_query(lib, query, album)

    # Walk through the items and pick up their changes.
    affected_albums = set()
    for item in items:
        # Item deleted?
        if not os.path.exists(syspath(item.path)):
            print_(u'X %s - %s' % (item.artist, item.title))
            lib.remove(item, True)
            affected_albums.add(item.album_id)
            continue

        # Read new data.
        old_data = dict(item.record)
        item.read()

        # Get and save metadata changes.
        changes = {}
        for key in library.ITEM_KEYS_META:
            if item.dirty[key]:
                changes[key] = old_data[key], getattr(item, key)
        if changes:
            # Something changed.
            print_(u'* %s - %s' % (item.artist, item.title))
            for key, (oldval, newval) in changes.iteritems():
                _showdiff(key, oldval, newval, color)

            # Move the item if it's in the library.
            if move and lib.directory in ancestry(item.path):
                item.move(lib)

            lib.store(item)
            affected_albums.add(item.album_id)

    # Modify affected albums to reflect changes in their items.
    for album_id in affected_albums:
        if album_id is None: # Singletons.
            continue
        album = lib.get_album(album_id)
        if not album: # Empty albums have already been removed.
            log.debug('emptied album %i' % album_id)
            continue
        al_items = list(album.items())

        # Update album structure to reflect an item in it.
        for key in library.ALBUM_KEYS_ITEM:
            setattr(album, key, getattr(al_items[0], key))

        # Move album art (and any inconsistent items).
        if move and lib.directory in ancestry(al_items[0].path):
            log.debug('moving album %i' % album_id)
            album.move()

    lib.save()
コード例 #55
0
ファイル: commands.py プロジェクト: MichaelB1105/filmreel
def modify_items(lib, mods, dels, query, write, move, album, confirm):
    """Modifies matching items according to key=value assignments."""
    # Parse key=value specifications into a dictionary.
    model_cls = library.Album if album else library.Item
    fsets = {}
    for mod in mods:
        key, value = mod.split('=', 1)
        fsets[key] = model_cls._parse(key, value)

    # Get the items to modify.
    items, albums = _do_query(lib, query, album, False)
    objs = albums if album else items

    # Apply changes *temporarily*, preview them, and collect modified
    # objects.
    print_('Modifying %i %ss.' % (len(objs), 'album' if album else 'item'))
    changed = set()
    for obj in objs:
        for field, value in fsets.iteritems():
            obj[field] = value
        for field in dels:
            del obj[field]
        if ui.show_model_changes(obj):
            changed.add(obj)

    # Still something to do?
    if not changed:
        print_('No changes to make.')
        return

    # Confirm action.
    if confirm:
        extra = ' and write tags' if write else ''
        if not ui.input_yn('Really modify%s (Y/n)?' % extra):
            return

    # Apply changes to database.
    with lib.transaction():
        for obj in changed:
            if move:
                cur_path = obj.path
                if lib.directory in ancestry(cur_path): # In library?
                    log.debug('moving object %s' % cur_path)
                    obj.move()

            obj.store()

    # Apply tags if requested.
    if write:
        if album:
            changed_items = itertools.chain(*(a.items() for a in changed))
        else:
            changed_items = changed
        for item in changed_items:
            try:
                item.write()
            except library.FileOperationError as exc:
                log.error(exc)
コード例 #56
0
ファイル: commands.py プロジェクト: aspidites/beets
def choose_match(task, config):
    """Given an initial autotagging of items, go through an interactive
    dance with the user to ask for a choice of metadata. Returns an
    (info, items) pair, ASIS, or SKIP.
    """
    # Show what we're tagging.
    print_()
    print_(task.path)

    if config.quiet:
        # No input; just make a decision.
        if task.rec == autotag.RECOMMEND_STRONG:
            dist, items, info = task.candidates[0]
            show_change(task.cur_artist, task.cur_album, items, info, dist, config.color)
            return info, items
        else:
            return _quiet_fall_back(config)

    # Loop until we have a choice.
    candidates, rec = task.candidates, task.rec
    while True:
        # Ask for a choice from the user.
        choice = choose_candidate(
            candidates,
            False,
            rec,
            config.color,
            config.timid,
            task.cur_artist,
            task.cur_album,
            itemcount=len(task.items),
            per_disc_numbering=config.per_disc_numbering,
        )

        # Choose which tags to use.
        if choice in (importer.action.SKIP, importer.action.ASIS, importer.action.TRACKS):
            # Pass selection to main control flow.
            return choice
        elif choice is importer.action.MANUAL:
            # Try again with manual search terms.
            search_artist, search_album = manual_search(False)
            try:
                _, _, candidates, rec = autotag.tag_album(task.items, config.timid, search_artist, search_album)
            except autotag.AutotagError:
                candidates, rec = None, None
        elif choice is importer.action.MANUAL_ID:
            # Try a manually-entered ID.
            search_id = manual_id(False)
            if search_id:
                try:
                    _, _, candidates, rec = autotag.tag_album(task.items, config.timid, search_id=search_id)
                except autotag.AutotagError:
                    candidates, rec = None, None
        else:
            # We have a candidate! Finish tagging. Here, choice is
            # an (info, items) pair as desired.
            assert not isinstance(choice, importer.action)
            return choice
コード例 #57
0
ファイル: lyrics.py プロジェクト: coolkehon/beets
 def func(lib, config, opts, args):
     # The "write to files" option corresponds to the
     # import_write config value.
     write = ui.config_val(config, 'beets', 'import_write',
                           commands.DEFAULT_IMPORT_WRITE, bool)
     for item in lib.items(ui.decargs(args)):
         fetch_item_lyrics(lib, logging.INFO, item, write)
         if opts.printlyr and item.lyrics:
             ui.print_(item.lyrics)
コード例 #58
0
ファイル: modifytmpl.py プロジェクト: kergoth/beets-kergoth
    def modify_items(self, lib, mods, dels, query, write, move, album,
                     confirm):
        """Modifies matching items according to user-specified assignments and
        deletions.

        `mods` is a dictionary of field and value pairse indicating
        assignments. `dels` is a list of fields to be deleted.
        """
        # Parse key=value specifications into a dictionary.
        model_cls = library.Album if album else library.Item

        # Get the items to modify.
        items, albums = _do_query(lib, query, album, False)
        objs = albums if album else items

        reconfirm = self.check_sanity(mods, dels, objs, album)
        if reconfirm:
            confirm = True

        # Apply changes *temporarily*, preview them, and collect modified
        # objects.
        print_(u'Modifying {0} {1}s.'.format(len(objs),
                                             u'album' if album else u'item'))
        changed = []
        for obj in objs:
            obj_mods = {}
            for key, value in mods.items():
                value = obj.evaluate_template(value)
                obj_mods[key] = model_cls._parse(key, value)

            if print_and_modify(obj, obj_mods, dels) and obj not in changed:
                changed.append(obj)

        # Still something to do?
        if not changed:
            print_(u'No changes to make.')
            return

        # Confirm action.
        if confirm:
            if write and move:
                extra = u', move and write tags'
            elif write:
                extra = u' and write tags'
            elif move:
                extra = u' and move'
            else:
                extra = u''

            changed = ui.input_select_objects(
                u'Really modify%s' % extra, changed,
                lambda o: print_and_modify(o, mods, dels))

        # Apply changes to database and files
        with lib.transaction():
            for obj in changed:
                obj.try_sync(write, move)
コード例 #59
0
ファイル: echonest_tempo.py プロジェクト: colin-scott/beets
        def func(lib, opts, args):
            # The "write to files" option corresponds to the
            # import_write config value.
            write = config['import']['write'].get(bool)

            for item in lib.items(ui.decargs(args)):
                fetch_item_tempo(lib, logging.INFO, item, write)
                if opts.printbpm and item.bpm:
                    ui.print_('{0} BPM'.format(item.bpm))
コード例 #60
0
ファイル: echonest_tempo.py プロジェクト: toddbot2/beets
        def func(lib, opts, args):
            # The "write to files" option corresponds to the
            # import_write config value.
            write = config['import']['write'].get(bool)

            for item in lib.items(ui.decargs(args)):
                fetch_item_tempo(lib, logging.INFO, item, write)
                if opts.printbpm and item.bpm:
                    ui.print_('{0} BPM'.format(item.bpm))