示例#1
0
文件: zero.py 项目: JDLH/beets
 def zero_fields(lib, opts, args):
     if not decargs(args) and not input_yn(
             u"Remove fields for all items? (Y/n)",
             True):
         return
     for item in lib.items(decargs(args)):
         self.process_item(item)
示例#2
0
        def embed_func(lib, opts, args):
            if opts.file:
                imagepath = normpath(opts.file)
                if not os.path.isfile(syspath(imagepath)):
                    raise ui.UserError(u'image file {0} not found'.format(
                        displayable_path(imagepath)
                    ))

                items = lib.items(decargs(args))

                # Confirm with user.
                if not opts.yes and not _confirm(items, not opts.file):
                    return

                for item in items:
                    art.embed_item(self._log, item, imagepath, maxwidth, None,
                                   compare_threshold, ifempty)
            else:
                albums = lib.albums(decargs(args))

                # Confirm with user.
                if not opts.yes and not _confirm(albums, not opts.file):
                    return

                for album in albums:
                    art.embed_album(self._log, album, maxwidth, False,
                                    compare_threshold, ifempty)
                    self.remove_artfile(album)
示例#3
0
文件: __init__.py 项目: beetbox/beets
        def lastgenre_func(lib, opts, args):
            write = ui.should_write()
            self.config.set_args(opts)

            if opts.album:
                # Fetch genres for whole albums
                for album in lib.albums(ui.decargs(args)):
                    album.genre, src = self._get_genre(album)
                    self._log.info(u'genre for album {0} ({1}): {0.genre}',
                                   album, src)
                    album.store()

                    for item in album.items():
                        # If we're using track-level sources, also look up each
                        # track on the album.
                        if 'track' in self.sources:
                            item.genre, src = self._get_genre(item)
                            item.store()
                            self._log.info(
                                u'genre for track {0} ({1}): {0.genre}',
                                item, src)

                        if write:
                            item.try_write()
            else:
                # Just query singletons, i.e. items that are not part of
                # an album
                for item in lib.items(ui.decargs(args)):
                    item.genre, src = self._get_genre(item)
                    self._log.debug(u'added last.fm item genre ({0}): {1}',
                                    src, item.genre)
                    item.store()
示例#4
0
        def func(lib, opts, args):
            write = config['import']['write'].get(bool)

            if opts.album:
                # Analyze albums.
                for album in lib.albums(ui.decargs(args)):
                    log.info(u'analyzing {0} - {1}'.format(album.albumartist,
                                                           album.album))
                    items = list(album.items())
                    results = self.compute_rgain(items, True)
                    if results:
                        self.store_gain(lib, items, results, album)

                    if write:
                        for item in items:
                            item.write()

            else:
                # Analyze individual tracks.
                for item in lib.items(ui.decargs(args)):
                    log.info(u'analyzing {0} - {1}'.format(item.artist,
                                                           item.title))
                    results = self.compute_rgain([item], False)
                    if results:
                        self.store_gain(lib, [item], results, None)

                    if write:
                        item.write()
示例#5
0
        def func(lib, config, opts, args):
            write = ui.config_val(config, "beets", "import_write", commands.DEFAULT_IMPORT_WRITE, bool)

            if opts.album:
                # Analyze albums.
                for album in lib.albums(ui.decargs(args)):
                    log.info("analyzing {0} - {1}".format(album.albumartist, album.album))
                    items = list(album.items())
                    results = self.compute_rgain(items, True)
                    if results:
                        self.store_gain(lib, items, results, album)

                    if write:
                        for item in items:
                            item.write()

            else:
                # Analyze individual tracks.
                for item in lib.items(ui.decargs(args)):
                    log.info("analyzing {0} - {1}".format(item.artist, item.title))
                    results = self.compute_rgain([item], False)
                    if results:
                        self.store_gain(lib, [item], results, None)

                    if write:
                        item.write()
示例#6
0
def convert_func(lib, opts, args):
    dest = opts.dest if opts.dest is not None else \
            config['convert']['dest'].get()

    if not dest:
        raise ui.UserError('no convert destination set')

    dest = util.bytestring_path(dest)
    threads = opts.threads if opts.threads is not None else \
            config['convert']['threads'].get(int)
    keep_new = opts.keep_new

    if not config['convert']['paths']:
        path_formats = ui.get_path_formats()
    else:
        path_formats = ui.get_path_formats(config['convert']['paths'])

    ui.commands.list_items(lib, ui.decargs(args), opts.album, None)

    if not ui.input_yn("Convert? (Y/n)"):
        return

    if opts.album:
        items = (i for a in lib.albums(ui.decargs(args)) for i in a.items())
    else:
        items = iter(lib.items(ui.decargs(args)))
    convert = [convert_item(lib, dest, keep_new, path_formats) for i in range(threads)]
    pipe = util.pipeline.Pipeline([items, convert])
    pipe.run_parallel()
示例#7
0
文件: play.py 项目: 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))
示例#8
0
 def embed_func(lib, opts, args):
     if opts.file:
         imagepath = normpath(opts.file)
         for item in lib.items(decargs(args)):
             embed_item(item, imagepath, maxwidth)
     else:
         for album in lib.albums(decargs(args)):
             embed_album(album, maxwidth)
示例#9
0
        def _dup(lib, opts, args):
            self.config.set_args(opts)
            album = self.config['album'].get(bool)
            checksum = self.config['checksum'].get(str)
            copy = self.config['copy'].get(str)
            count = self.config['count'].get(bool)
            delete = self.config['delete'].get(bool)
            fmt = self.config['format'].get(str)
            full = self.config['full'].get(bool)
            keys = self.config['keys'].get(list)
            merge = self.config['merge'].get(bool)
            move = self.config['move'].get(str)
            path = self.config['path'].get(bool)
            tiebreak = self.config['tiebreak'].get(dict)
            strict = self.config['strict'].get(bool)
            tag = self.config['tag'].get(str)

            if album:
                if not keys:
                    keys = ['mb_albumid']
                items = lib.albums(decargs(args))
            else:
                if not keys:
                    keys = ['mb_trackid', 'mb_albumid']
                items = lib.items(decargs(args))

            if path:
                fmt = '$path'

            # Default format string for count mode.
            if count and not fmt:
                if album:
                    fmt = '$albumartist - $album'
                else:
                    fmt = '$albumartist - $album - $title'
                fmt += ': {0}'

            if checksum:
                for i in items:
                    k, _ = self._checksum(i, checksum)
                keys = [k]

            for obj_id, obj_count, objs in self._duplicates(items,
                                                            keys=keys,
                                                            full=full,
                                                            strict=strict,
                                                            tiebreak=tiebreak,
                                                            merge=merge):
                if obj_id:  # Skip empty IDs.
                    for o in objs:
                        self._process_item(o,
                                           copy=copy,
                                           move=move,
                                           delete=delete,
                                           tag=tag,
                                           fmt=fmt.format(obj_count))
示例#10
0
        def func(lib, opts, args):
            write = ui.should_write()

            if opts.album:
                for album in lib.albums(ui.decargs(args)):
                    self.handle_album(album, write)

            else:
                for item in lib.items(ui.decargs(args)):
                    self.handle_track(item, write)
示例#11
0
        def func(lib, opts, args):
            write = config['import']['write'].get(bool)

            if opts.album:
                for album in lib.albums(ui.decargs(args)):
                    self.handle_album(album, write)

            else:
                for item in lib.items(ui.decargs(args)):
                    self.handle_track(item, write)
示例#12
0
文件: embedart.py 项目: pkess/beets
 def embed_func(lib, opts, args):
     if opts.file:
         imagepath = normpath(opts.file)
         if not os.path.isfile(syspath(imagepath)):
             raise ui.UserError(u"image file {0} not found".format(displayable_path(imagepath)))
         for item in lib.items(decargs(args)):
             art.embed_item(self._log, item, imagepath, maxwidth, None, compare_threshold, ifempty)
     else:
         for album in lib.albums(decargs(args)):
             art.embed_album(self._log, album, maxwidth, False, compare_threshold, ifempty)
             self.remove_artfile(album)
示例#13
0
        def func(lib, opts, args):
            self._log.setLevel(logging.INFO)

            write = ui.should_write()

            if opts.album:
                for album in lib.albums(ui.decargs(args)):
                    self.handle_album(album, write)

            else:
                for item in lib.items(ui.decargs(args)):
                    self.handle_track(item, write)
示例#14
0
        def _dup(lib, opts, args):
            self.config.set_args(opts)
            fmt = self.config['format'].get()
            album = self.config['album'].get(bool)
            full = self.config['full'].get(bool)
            strict = self.config['strict'].get(bool)
            keys = self.config['keys'].get()
            checksum = self.config['checksum'].get()
            copy = self.config['copy'].get()
            move = self.config['move'].get()
            delete = self.config['delete'].get(bool)
            tag = self.config['tag'].get()

            if album:
                keys = ['mb_albumid']
                items = lib.albums(decargs(args))
            else:
                items = lib.items(decargs(args))

            if self.config['path']:
                fmt = '$path'

            # Default format string for count mode.
            if self.config['count'] and not fmt:
                if album:
                    fmt = '$albumartist - $album'
                else:
                    fmt = '$albumartist - $album - $title'
                fmt += ': {0}'

            if checksum:
                if not isinstance(checksum, basestring):
                    raise UserError(
                        'duplicates: "checksum" option must be a command'
                    )
                for i in items:
                    k, _ = self._checksum(i, checksum)
                keys = [k]

            for obj_id, obj_count, objs in self._duplicates(items,
                                                            keys=keys,
                                                            full=full,
                                                            strict=strict):
                if obj_id:  # Skip empty IDs.
                    for o in objs:
                        self._process_item(o, lib,
                                           copy=copy,
                                           move=move,
                                           delete=delete,
                                           tag=tag,
                                           fmt=fmt.format(obj_count))
示例#15
0
    def encode(self, command, source, dest, pretend=False):
        """Encode `source` to `dest` using command template `command`.

        Raises `subprocess.CalledProcessError` if the command exited with a
        non-zero status code.
        """
        # The paths and arguments must be bytes.
        assert isinstance(command, bytes)
        assert isinstance(source, bytes)
        assert isinstance(dest, bytes)

        quiet = self.config['quiet'].get(bool)

        if not quiet and not pretend:
            self._log.info(u'Encoding {0}', util.displayable_path(source))

        # Substitute $source and $dest in the argument list.
        args = shlex.split(command)
        for i, arg in enumerate(args):
            args[i] = Template(arg).safe_substitute({
                'source': source,
                'dest': dest,
            })

        if pretend:
            self._log.info(u' '.join(ui.decargs(args)))
            return

        try:
            util.command_output(args)
        except subprocess.CalledProcessError as exc:
            # Something went wrong (probably Ctrl+C), remove temporary files
            self._log.info(u'Encoding {0} failed. Cleaning up...',
                           util.displayable_path(source))
            self._log.debug(u'Command {0} exited with status {1}: {2}',
                            args,
                            exc.returncode,
                            exc.output)
            util.remove(dest)
            util.prune_dirs(os.path.dirname(dest))
            raise
        except OSError as exc:
            raise ui.UserError(
                u"convert: couldn't invoke '{0}': {1}".format(
                    u' '.join(ui.decargs(args)), exc
                )
            )

        if not quiet and not pretend:
            self._log.info(u'Finished encoding {0}',
                           util.displayable_path(source))
示例#16
0
文件: info.py 项目: beetbox/beets
    def run(self, lib, opts, args):
        """Print tag info or library data for each file referenced by args.

        Main entry point for the `beet info ARGS...` command.

        If an argument is a path pointing to an existing file, then the tags
        of that file are printed. All other arguments are considered
        queries, and for each item matching all those queries the tags from
        the file are printed.

        If `opts.summarize` is true, the function merges all tags into one
        dictionary and only prints that. If two files have different values
        for the same tag, the value is set to '[various]'
        """
        if opts.library:
            data_collector = library_data
        else:
            data_collector = tag_data

        included_keys = []
        for keys in opts.included_keys:
            included_keys.extend(keys.split(','))
        # Drop path even if user provides it multiple times
        included_keys = [k for k in included_keys if k != 'path']
        key_filter = make_key_filter(included_keys)

        first = True
        summary = {}
        for data_emitter in data_collector(lib, ui.decargs(args)):
            try:
                data, item = data_emitter()
            except (mediafile.UnreadableFileError, IOError) as ex:
                self._log.error(u'cannot read file: {0}', ex)
                continue

            data = key_filter(data)
            if opts.summarize:
                update_summary(summary, data)
            else:
                if not first:
                    ui.print_()
                if opts.keys_only:
                    print_data_keys(data, item)
                else:
                    fmt = ui.decargs([opts.format])[0] if opts.format else None
                    print_data(data, item, fmt)
                first = False

        if opts.summarize:
            print_data(summary)
示例#17
0
文件: embedart.py 项目: pkess/beets
 def extract_func(lib, opts, args):
     if opts.outpath:
         art.extract_first(self._log, normpath(opts.outpath), lib.items(decargs(args)))
     else:
         filename = bytestring_path(opts.filename or config["art_filename"].get())
         if os.path.dirname(filename) != "":
             self._log.error(u"Only specify a name rather than a path for -n")
             return
         for album in lib.albums(decargs(args)):
             artpath = normpath(os.path.join(album.path, filename))
             artpath = art.extract_first(self._log, artpath, album.items())
             if artpath and opts.associate:
                 album.set_art(artpath)
                 album.store()
示例#18
0
        def _dup(lib, opts, args):
            self.config.set_args(opts)
            fmt = self.config['format'].get()
            path = self.config['path'].get()
            count = self.config['count'].get()
            album = self.config['album'].get()
            full = self.config['full'].get()
            keys = self.config['keys'].get()
            checksum = self.config['checksum'].get()
            copy = self.config['copy'].get()
            move = self.config['move'].get()
            delete = self.config['delete'].get()
            delete_file = self.config['delete_file'].get()
            tag = self.config['tag'].get()

            if album:
                keys = ['mb_albumid']
                items = lib.albums(decargs(args))
            else:
                items = lib.items(decargs(args))

            if path:
                fmt = '$path'

            # Default format string for count mode.
            if count and not fmt:
                if album:
                    fmt = '$albumartist - $album'
                else:
                    fmt = '$albumartist - $album - $title'
                fmt += ': {0}'

            if checksum:
                for i in items:
                    k, _ = _checksum(i, checksum)
                keys = ['k']

            for obj_id, obj_count, objs in _duplicates(items,
                                                       keys=keys,
                                                       full=full):
                if obj_id:  # Skip empty IDs.
                    for o in objs:
                        _process_item(o, lib,
                                      copy=copy,
                                      move=move,
                                      delete=delete if delete else delete_file,
                                      tag=tag,
                                      format=fmt.format(obj_count))
示例#19
0
        def _dup(lib, opts, args):
            self.config.set_args(opts)
            album = self.config["album"].get(bool)
            checksum = self.config["checksum"].get(str)
            copy = self.config["copy"].get(str)
            count = self.config["count"].get(bool)
            delete = self.config["delete"].get(bool)
            fmt = self.config["format"].get(str)
            full = self.config["full"].get(bool)
            keys = self.config["keys"].get(list)
            merge = self.config["merge"].get(bool)
            move = self.config["move"].get(str)
            path = self.config["path"].get(bool)
            tiebreak = self.config["tiebreak"].get(dict)
            strict = self.config["strict"].get(bool)
            tag = self.config["tag"].get(str)

            if album:
                if not keys:
                    keys = ["mb_albumid"]
                items = lib.albums(decargs(args))
            else:
                if not keys:
                    keys = ["mb_trackid", "mb_albumid"]
                items = lib.items(decargs(args))

            if path:
                fmt = "$path"

            # Default format string for count mode.
            if count and not fmt:
                if album:
                    fmt = "$albumartist - $album"
                else:
                    fmt = "$albumartist - $album - $title"
                fmt += ": {0}"

            if checksum:
                for i in items:
                    k, _ = self._checksum(i, checksum)
                keys = [k]

            for obj_id, obj_count, objs in self._duplicates(
                items, keys=keys, full=full, strict=strict, tiebreak=tiebreak, merge=merge
            ):
                if obj_id:  # Skip empty IDs.
                    for o in objs:
                        self._process_item(o, copy=copy, move=move, delete=delete, tag=tag, fmt=fmt.format(obj_count))
示例#20
0
文件: badfiles.py 项目: drm00/beets
    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)))
示例#21
0
 def func(lib, opts, args):
     write = config['import']['write'].get(bool)
     for item in lib.items(ui.decargs(args)):
         ft_in_title(item)
         item.store()
         if write:
             item.write()
示例#22
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)
示例#23
0
        def func(lib, opts, args):
            args = ui.decargs(args)
            if args:
                self.config['host'] = args.pop(0)
            if args:
                self.config['port'] = int(args.pop(0))

            app.config['lib'] = lib
            # Normalizes json output
            app.config['JSONIFY_PRETTYPRINT_REGULAR'] = False

            app.config['INCLUDE_PATHS'] = self.config['include_paths']

            # Enable CORS if required.
            if self.config['cors']:
                self._log.info(u'Enabling CORS with origin: {0}',
                               self.config['cors'])
                from flask.ext.cors import CORS
                app.config['CORS_ALLOW_HEADERS'] = "Content-Type"
                app.config['CORS_RESOURCES'] = {
                    r"/*": {"origins": self.config['cors'].get(str)}
                }
                CORS(app)
            # Start the web application.
            app.run(host=self.config['host'].as_str(),
                    port=self.config['port'].get(int),
                    debug=opts.debug, threaded=True)
示例#24
0
文件: rdm.py 项目: nidico/beets
def random_item(lib, config, opts, args):
    query = decargs(args)
    path = opts.path
    fmt = opts.format

    if fmt is None:
        # If no specific template is supplied, use a default
        if opts.album:
            fmt = u'$albumartist - $album'
        else:
            fmt = u'$artist - $album - $title'
    template = Template(fmt)

    if opts.album:
        objs = list(lib.albums(query=query))
    else:
        objs = list(lib.items(query=query))
    number = min(len(objs), opts.number)
    objs = random.sample(objs, number)

    if opts.album:
        for album in objs:
            if path:
                print_(album.item_dir())
            else:
                print_(album.evaluate_template(template))
    else:
        for item in objs:
            if path:
                print_(item.path)
            else:
                print_(item.evaluate_template(template, lib))
示例#25
0
    def commanded(self, lib, opts, args):
        """wlg as command"""
        if not self.wlg:
            self.setup(opts.cache, opts.verbose)

        if opts.force:
            self.config['force'] = True

        albums = lib.albums(decargs(args))
        i = 1
        try:
            for i, album in enumerate(albums, start=1):
                self._log.info(whatlastgenre.progressbar(i, len(albums)))
                genres = self.genres(album)
                if album.genre != genres:
                    album.genre = genres
                    album.store()
                    for item in album.items():
                        item.genre = genres
                        item.store()
                        if config['import']['write'].get(bool):
                            item.try_write()
        except KeyboardInterrupt:
            pass

        self.wlg.print_stats(i)
        self.setdown()
示例#26
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)
示例#27
0
文件: genrelist.py 项目: michl/beets
def update_genres(lib, config, opts, args):
	global genres
	global fallback_str
	for item in lib.items(ui.decargs(args)):
		if item.album_id is not None:
			continue
		genre = get_genre(item.artist, genres)
		log.warn("title: %s, artist: %s, genre: %s" % (item.title, item.artist, genre))
		if not genre and fallback_str != None:
			genre = fallback_str
			log.warn(u'no genre for %s in list: fallback to %s' % (item.artist, genre))
		if genre is not None:
			log.warn(u'adding genre for %s from list: %s' % (item.artist, genre))
		item.genre = genre
		lib.store(item)
		item.write()

	for album in lib.albums():
		genre = get_genre(album.albumartist, genres)
		if (genre is None) and (fallback_str is not None):
			genre = fallback_str
			log.warn(u'no genre for %s in list: fallback to %s' % (album.albumartist, genre))
		if genre is not None:
			log.warn(u'adding genre for %s from list: %s' % (album.albumartist, genre))
			bluo=''
		album.genre = genre
		for item in album.items():
			item.write()
示例#28
0
文件: fuzzy.py 项目: flz/beets
def fuzzy_list(lib, opts, args):
    query = decargs(args)
    query = ' '.join(query).lower()
    queryMatcher = difflib.SequenceMatcher(b=query)

    if opts.threshold is not None:
        threshold = float(opts.threshold)
    else:
        threshold = config['fuzzy']['threshold'].as_number()

    if opts.path:
        fmt = '$path'
    else:
        fmt = opts.format
    template = Template(fmt) if fmt else None

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

    items = filter(lambda i: is_match(queryMatcher, i, album=opts.album,
                                      threshold=threshold), objs)

    for item in items:
        print_obj(item, lib, template)
        if opts.verbose:
            print(is_match(queryMatcher, item,
                           album=opts.album, verbose=True)[1])
示例#29
0
文件: scrub.py 项目: dreewoo/beets
        def scrub_func(lib, opts, args):
            # This is a little bit hacky, but we set a global flag to
            # avoid autoscrubbing when we're also explicitly scrubbing.
            global scrubbing
            scrubbing = True

            # Walk through matching files and remove tags.
            for item in lib.items(ui.decargs(args)):
                log.info(u'scrubbing: {0}', util.displayable_path(item.path))

                # Get album art if we need to restore it.
                if opts.write:
                    mf = mediafile.MediaFile(item.path,
                                             config['id3v23'].get(bool))
                    art = mf.art

                # Remove all tags.
                _scrub(item.path)

                # Restore tags, if enabled.
                if opts.write:
                    log.debug(u'writing new tags after scrub')
                    item.try_write()
                    if art:
                        log.info(u'restoring art')
                        mf = mediafile.MediaFile(item.path)
                        mf.art = art
                        mf.save()

            scrubbing = False
示例#30
0
        def lastgenre_func(lib, opts, args):
            write = config['import']['write'].get(bool)
            self.config.set_args(opts)

            for album in lib.albums(ui.decargs(args)):
                album.genre, src = self._get_genre(album)
                log.info(u'genre for album {0} - {1} ({2}): {3}'.format(
                    album.albumartist, album.album, src, album.genre
                ))
                album.store()

                for item in album.items():
                    # If we're using track-level sources, also look up each
                    # track on the album.
                    if 'track' in self.sources:
                        item.genre, src = self._get_genre(item)
                        item.store()
                        log.info(
                            u'genre for track {0} - {1} ({2}): {3}'. format(
                                item.artist, item.title, src, item.genre
                            )
                        )

                    if write:
                        item.try_write()
示例#31
0
        def func(lib, opts, args):
            self.config.set_args(opts)
            drop_feat = self.config['drop'].get(bool)
            write = ui.should_write()

            for item in lib.items(ui.decargs(args)):
                self.ft_in_title(item, drop_feat)
                item.store()
                if write:
                    item.try_write()
示例#32
0
        def func(lib, opts, args):
            self.config.set_args(opts)
            drop_feat = self.config['drop'].get(bool)
            write = config['import']['write'].get(bool)

            for item in lib.items(ui.decargs(args)):
                ft_in_title(item, drop_feat, logging.INFO)
                item.store()
                if write:
                    item.try_write()
示例#33
0
        def func(lib, opts, args):
            self.config.set_args(opts)
            force_parent = self.config['force'].get(bool)
            write = ui.should_write()

            for item in lib.items(ui.decargs(args)):
                self.find_work(item, force_parent)
                item.store()
                if write:
                    item.try_write()
示例#34
0
    def func(self, lib: Library, options, arguments):
        self.lib = lib
        self.query = decargs(arguments)
        self.cfg_force = options.force

        if options.version:
            self.show_version_information()
            return

        self.handle_main_task()
示例#35
0
 def func(lib, opts, args):
     self.config.set_args(opts)
     for item in lib.items(ui.decargs(args)):
         log.info(u'echonest: {0} - {1} [{2}]'.format(item.artist,
                 item.title, item.length))
         if self.config['force'] or self.requires_update(item):
             song = self.fetch_song(item)
             if not song is None:
                 self._songs[item.path] = song
             self.apply_metadata(item)
示例#36
0
 def do_normalize(self, lib, opts, args):
     objs = []
     query = ui.decargs(args)
     if opts.album:
         [[objs.append(item) for item in album.items()]
          for album in lib.albums(query)]
     else:
         [objs.append(item) for item in lib.items(query)]
     for item in objs:
         self.process_file(item)
示例#37
0
文件: bpsync.py 项目: adamjakab/Beets
    def func(self, lib, opts, args):
        """Command handler for the bpsync function.
        """
        move = ui.should_move(opts.move)
        pretend = opts.pretend
        write = ui.should_write(opts.write)
        query = ui.decargs(args)

        self.singletons(lib, query, move, pretend, write)
        self.albums(lib, query, move, pretend, write)
示例#38
0
def mbsync_func(lib, opts, args):
    """Command handler for the mbsync function.
    """
    move = opts.move
    pretend = opts.pretend
    write = opts.write
    query = ui.decargs(args)

    mbsync_singletons(lib, query, move, pretend, write)
    mbsync_albums(lib, query, move, pretend, write)
示例#39
0
 def fetch_func(lib, opts, args):
     self.config.set_args(opts)
     write = config['import']['write'].get(bool)
     for item in lib.items(ui.decargs(args)):
         log.info(u'echonest: {0} - {1}'.format(item.artist,
                                                item.title))
         if self.config['force'] or self.requires_update(item):
             song = self.fetch_song(item)
             if song:
                 self.apply_metadata(item, song, write)
示例#40
0
    def convert_func(self, lib, opts, args):
        if not opts.dest:
            opts.dest = self.config['dest'].get()
        if not opts.dest:
            raise ui.UserError(u'no convert destination set')
        opts.dest = util.bytestring_path(opts.dest)

        if not opts.threads:
            opts.threads = self.config['threads'].get(int)

        if self.config['paths']:
            path_formats = ui.get_path_formats(self.config['paths'])
        else:
            path_formats = ui.get_path_formats()

        if not opts.format:
            opts.format = self.config['format'].as_str().lower()

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

        if not pretend:
            ui.commands.list_items(lib, ui.decargs(args), opts.album)

            if not (opts.yes or ui.input_yn(u"Convert? (Y/n)")):
                return

        if opts.album:
            albums = lib.albums(ui.decargs(args))
            items = (i for a in albums for i in a.items())
            if self.config['copy_album_art']:
                for album in albums:
                    self.copy_album_art(album, opts.dest, path_formats,
                                        pretend)
        else:
            items = iter(lib.items(ui.decargs(args)))
        convert = [
            self.convert_item(opts.dest, opts.keep_new, path_formats,
                              opts.format, pretend)
            for _ in range(opts.threads)
        ]
        pipe = util.pipeline.Pipeline([items, convert])
        pipe.run_parallel()
示例#41
0
    def func(self, lib, opts, args):
        self._log.debug("func called")

        self.library = lib

        # TODO: Allow querying for subset of library
        query = ui.decargs(args)

        results = self.perform_audit()

        print(json.dumps(results, ensure_ascii=False))
示例#42
0
 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)
示例#43
0
文件: convert.py 项目: Lugoues/beets
def convert_func(lib, opts, args):
    dest = opts.dest if opts.dest is not None else \
            config['convert']['dest'].get()
    if not dest:
        raise ui.UserError('no convert destination set')
    threads = opts.threads if opts.threads is not None else \
            config['convert']['threads'].get(int)

    ui.commands.list_items(lib, ui.decargs(args), opts.album, None)

    if not ui.input_yn("Convert? (Y/n)"):
        return

    if opts.album:
        items = (i for a in lib.albums(ui.decargs(args)) for i in a.items())
    else:
        items = lib.items(ui.decargs(args))
    convert = [convert_item(lib, dest) for i in range(threads)]
    pipe = util.pipeline.Pipeline([items, convert])
    pipe.run_parallel()
示例#44
0
        def func(lib, opts, args):
            args = ui.decargs(args)
            if args:
                self.config['host'] = args.pop(0)
            if args:
                self.config['port'] = int(args.pop(0))

            app.config['lib'] = lib
            app.run(host=self.config['host'].get(unicode),
                    port=self.config['port'].get(int),
                    debug=opts.debug, threaded=True)
示例#45
0
文件: mbsync.py 项目: ykumar6/beets
    def func(self, lib, opts, args):
        """Command handler for the mbsync function.
        """
        move = opts.move
        pretend = opts.pretend
        write = opts.write
        query = ui.decargs(args)
        fmt = opts.format

        self.singletons(lib, query, move, pretend, write, fmt)
        self.albums(lib, query, move, pretend, write, fmt)
示例#46
0
文件: commands.py 项目: encukou/beets
def list_func(lib, config, opts, args):
    fmt = opts.format
    if not fmt:
        # If no format is specified, fall back to a default.
        if opts.album:
            fmt = ui.config_val(config, 'beets', 'list_format_album',
                                DEFAULT_LIST_FORMAT_ALBUM)
        else:
            fmt = ui.config_val(config, 'beets', 'list_format_item',
                                DEFAULT_LIST_FORMAT_ITEM)
    list_items(lib, decargs(args), opts.album, opts.path, fmt)
示例#47
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)):
         self.fetch_item_lyrics(
             lib, logging.INFO, item, write,
             opts.force_refetch or self.config['force'],
         )
         if opts.printlyr and item.lyrics:
             ui.print_(item.lyrics)
 def command(self, lib, opts, args):
     write = ui.should_write()
     items = lib.items(ui.decargs(args))
     total_items = len(items)
     for num, item in enumerate(items):
         self._log.info(u'{0}/{1} {2}', num + 1, total_items,
                        util.displayable_path(item.path))
         new_comments = self.build_structured_comment(item)
         self._log.info(u'{0}', new_comments)
         if not opts.dry_run:
             if new_comments != item.comments or opts.force:
                 self.write_structured_comment(item, new_comments, write)
示例#49
0
 def handle_common_args(self, opts, args):
     self.config.set_args(opts)
     query = ui.decargs(args)
     if query:
         self.config["query"] = query
         self._log.debug(f'Using base query {" ".join(query)}')
         base_query, _ = library.parse_query_parts(query, library.Item)
     else:
         query = self.config["query"].as_str()
         self._log.debug(f"Using base query {query}")
         base_query, _ = library.parse_query_string(query, library.Item)
     self.base_query = base_query
示例#50
0
def modify_func(lib, config, opts, args):
    args = decargs(args)
    mods = [a for a in args if '=' in a]
    query = [a for a in args if '=' not in a]
    if not mods:
        raise ui.UserError('no modifications specified')
    write = opts.write if opts.write is not None else \
        ui.config_val(config, 'beets', 'import_write',
            DEFAULT_IMPORT_WRITE, bool)
    color = ui.config_val(config, 'beets', 'color', DEFAULT_COLOR, bool)
    modify_items(lib, mods, query, write, opts.move, opts.album, color,
                 not opts.yes)
示例#51
0
    def list_tracks(self, lib, options):
        if options.format is not None:
            fmt, = decargs([options.format])
            beets.config[beets.library.Item._format_config_key].set(fmt)

        alt = self.alternative(options.name, lib)

        # This is slow but we cannot use a native SQL query since the
        # path key is a flexible attribute
        for item in lib.items():
            if alt.path_key in item:
                print_(format(item))
示例#52
0
 def command(self, lib, opts, args):
     # Get items from arguments
     items = lib.items(ui.decargs(args))
     if sys.version_info[0] < 3:
         for item in items:
             self.analyze_submit(item)
     else:
         # Analyze in parallel using a thread pool.
         pool = ThreadPool()
         pool.map(self.analyze_submit, items)
         pool.close()
         pool.join()
示例#53
0
 def unidecode_list(self, lib, opts, args):
     """Emulate normal 'list' command but with unidecode output."""
     query = decargs(args)
     album = opts.album
     # Copied from commands.py - list_items
     if album:
         for album in lib.albums(query):
             bare = unidecode(str(album))
             print_(bare)
     else:
         for item in lib.items(query):
             bare = unidecode(str(item))
             print_(bare)
示例#54
0
        def func(lib, config, opts, args):
            # The "write to files" option corresponds to the
            # import_write config value.
            if not _echonest_apikey:
                raise ui.UserError('no EchoNest user API key provided')

            write = ui.config_val(config, 'beets', 'import_write',
                                  commands.DEFAULT_IMPORT_WRITE, bool)

            for item in lib.items(ui.decargs(args)):
                fetch_item_tempo(lib, logging.INFO, item, write)
                if opts.printlyr and item.bpm:
                    ui.print_(item.bpm)
示例#55
0
        def embed_func(lib, opts, args):
            if opts.file:
                imagepath = normpath(opts.file)
                if not os.path.isfile(syspath(imagepath)):
                    raise ui.UserError(u'image file {0} not found'.format(
                        displayable_path(imagepath)))
                for item in lib.items(decargs(args)):
                    art.embed_item(self._log, item, imagepath, maxwidth, None,
                                   compare_threshold, ifempty)
            else:
                for album in lib.albums(decargs(args)):
                    art.embed_album(self._log, album, maxwidth, False,
                                    compare_threshold, ifempty)

                    if remove_art_file and album.artpath is not None:
                        if os.path.isfile(album.artpath):
                            self._log.debug(
                                u'Removing album art file '
                                u'for {0}', album)
                            os.remove(album.artpath)
                            album.artpath = None
                            album.store()
示例#56
0
def convert_func(lib, opts, args):
    if not opts.dest:
        opts.dest = config['convert']['dest'].get()
    if not opts.dest:
        raise ui.UserError('no convert destination set')
    opts.dest = util.bytestring_path(opts.dest)

    if not opts.threads:
        opts.threads = config['convert']['threads'].get(int)

    if config['convert']['paths']:
        path_formats = ui.get_path_formats(config['convert']['paths'])
    else:
        path_formats = ui.get_path_formats()

    if not opts.format:
        opts.format = config['convert']['format'].get(unicode).lower()

    command, ext = get_format(opts.format)

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

    if not pretend:
        ui.commands.list_items(lib, ui.decargs(args), opts.album, None)

        if not ui.input_yn("Convert? (Y/n)"):
            return

    if opts.album:
        items = (i for a in lib.albums(ui.decargs(args)) for i in a.items())
    else:
        items = iter(lib.items(ui.decargs(args)))
    convert = [
        convert_item(opts.dest, opts.keep_new, path_formats, command, ext,
                     pretend) for _ in range(opts.threads)
    ]
    pipe = util.pipeline.Pipeline([items, convert])
    pipe.run_parallel()
示例#57
0
    def func(self, lib: Library, options, arguments):
        self.lib = lib
        self.query = decargs(arguments)

        # You must either pass a training name or request listing
        if len(self.query) < 1 and not options.version:
            self.parser.print_help()
            return

        if options.version:
            self.show_version_information()
            return

        self.handle_display()
示例#58
0
        def func(lib, opts, args):
            """Hook the arguments of the configuration-file."""
            args = ui.decargs(args)
            if args:
                self.config['host'] = args.pop(0)
            if args:
                self.config['port'] = int(args.pop(0))

            app.config['lib'] = lib
            # Start the Web-FrontEnd Plugin.
            app.run(host=self.config['host'].get(unicode),
                    port=self.config['port'].get(int),
                    debug=True,
                    threaded=True)
示例#59
0
    def commands(self):
        """
        Return the "userrating" ui subcommand.
        """

        cmd = ui.Subcommand('userrating',
                            help=u'manage user ratings for tracks')
        cmd.func = lambda lib, opts, args: self.handle_tracks(
            lib.items(ui.decargs(args)), opts)
        cmd.parser.add_option(
            u'-u',
            u'--update',
            action='store',
            help=u'all files will be rated with given value',
        )
        cmd.parser.add_option(
            u'-i',
            u'--imported',
            action='store_true',
            help=
            u'all files will be rated if possible with known players value in file',
        )
        cmd.parser.add_option(
            u'-o',
            u'--overwrite',
            action='store_true',
            help=
            u'allow overwriting rated file (default is to skip already rated file)',
        )
        cmd.parser.add_option(
            u'-s',
            u'--sync',
            action='store',
            help=
            u'write rating for existing players rating (default is to not update any players rating but beets)',
        )
        cmd.parser.add_option(
            u'-a',
            u'--all',
            action='store_true',
            help=
            u'write rating for all known players (default is to not update any players rating but beets)',
        )

        cmd2 = ui.Subcommand('ratingsfile',
                             help=u'write library ratings to playlist file')
        cmd2.func = lambda lib, opts, args: self.write_ratings_file(lib)

        return [cmd, cmd2]
示例#60
0
文件: random.py 项目: adamjakab/Beets
def random_func(lib, opts, args):
    """Select some random items or albums and print the results.
    """
    # Fetch all the objects matching the query into a list.
    query = decargs(args)
    if opts.album:
        objs = list(lib.albums(query))
    else:
        objs = list(lib.items(query))

    # Print a random subset.
    objs = random_objs(objs, opts.album, opts.number, opts.time,
                       opts.equal_chance)
    for obj in objs:
        print_(format(obj))