示例#1
0
    def truncate(self, source):
        """Truncates an item to a size less than UPLOAD_MAX_SIZE."""
        fd, dest = tempfile.mkstemp(u'.ogg')
        os.close(fd)

        log.info(u'echonest: truncating {0} to {1}',
                 util.displayable_path(source),
                 util.displayable_path(dest))

        opts = []
        for arg in TRUNCATE_COMMAND.split():
            arg = arg.encode('utf-8')
            opts.append(Template(arg).substitute(source=source, dest=dest))

        # Run the command.
        try:
            util.command_output(opts)
        except (OSError, subprocess.CalledProcessError) as exc:
            log.debug(u'echonest: truncate failed: {0}', exc)
            util.remove(dest)
            return

        log.info(u'echonest: truncate encoding {0}',
                 util.displayable_path(source))
        return dest
示例#2
0
def im_resize(maxwidth, path_in, path_out=None):
    """Resize using ImageMagick.

    Use the ``magick`` program or ``convert`` on older versions. Return
    the output path of resized image.
    """
    path_out = path_out or temp_file_for(path_in)
    log.debug(u'artresizer: ImageMagick resizing {0} to {1}',
              util.displayable_path(path_in), util.displayable_path(path_out))

    # "-resize WIDTHx>" shrinks images with the width larger
    # than the given width while maintaining the aspect ratio
    # with regards to the height.
    cmd = ArtResizer.shared.im_convert_cmd + \
        [util.syspath(path_in, prefix=False),
            '-resize', '{0}x>'.format(maxwidth),
            util.syspath(path_out, prefix=False)]

    try:
        util.command_output(cmd)
    except subprocess.CalledProcessError:
        log.warning(u'artresizer: IM convert failed for {0}',
                    util.displayable_path(path_in))
        return path_in

    return path_out
示例#3
0
    def convert(self, item):
        """Converts an item in an unsupported media format to ogg.  Config
        pending.
        This is stolen from Jakob Schnitzers convert plugin.
        """
        fd, dest = tempfile.mkstemp(u'.ogg')
        os.close(fd)
        source = item.path

        log.info(u'echonest: encoding {0} to {1}'.format(
            util.displayable_path(source),
            util.displayable_path(dest),
        ))

        # Build up the FFmpeg command line.
        # FIXME: use avconv?
        command = u'ffmpeg -i $source -y -acodec libvorbis -vn -aq 2 $dest'
        opts = []
        for arg in command.split():
            arg = arg.encode('utf-8')
            opts.append(Template(arg).substitute(source=source, dest=dest))

        # Run the command.
        try:
            util.command_output(opts)
        except (OSError, subprocess.CalledProcessError) as exc:
            log.debug(u'echonest: encode failed: {0}'.format(exc))
            util.remove(dest)
            return

        log.info(u'echonest: finished encoding {0}'.format(
            util.displayable_path(source))
        )
        return dest
示例#4
0
    def truncate(self, item):
        """Truncates an item to a size less than UPLOAD_MAX_SIZE."""
        fd, dest = tempfile.mkstemp(u'.ogg')
        os.close(fd)
        source = item.path

        log.info(u'echonest: truncating {0} to {1}'.format(
            util.displayable_path(source),
            util.displayable_path(dest),
        ))

        command = u'ffmpeg -t 300 -i $source -y -acodec copy $dest'
        opts = []
        for arg in command.split():
            arg = arg.encode('utf-8')
            opts.append(Template(arg).substitute(source=source, dest=dest))

        # Run the command.
        try:
            util.command_output(opts)
        except (OSError, subprocess.CalledProcessError) as exc:
            log.debug(u'echonest: truncate failed: {0}'.format(exc))
            util.remove(dest)
            return

        log.info(u'echonest: truncate encoding {0}'.format(
            util.displayable_path(source))
        )
        return dest
示例#5
0
    def item_candidates(self, item, artist, album):
        dir = path.dirname(item.path)
        cues = glob.glob(path.join(dir, "*.cue"))
        if not cues:
            return
        if len(cues) > 1:
            self._log.info(u"Found multiple cue files doing nothing: {0}",
                           map(displayable_path, cues))

        cue_file = cues[0]
        self._log.info("Found {} for {}", displayable_path(cue_file), item)

        try:
            # careful: will ask for input in case of conflicts
            command_output(['shnsplit', '-f', cue_file, item.path])
        except (subprocess.CalledProcessError, OSError):
            self._log.exception(u'shnsplit execution failed')
            return

        tracks = glob(path.join(dir, "*.wav"))
        self._log.info("Generated {0} tracks", len(tracks))
        for t in tracks:
            title = "dunno lol"
            track_id = "wtf"
            index = int(path.basename(t)[len("split-track"):-len(".wav")])
            yield TrackInfo(title, track_id, index=index, artist=artist)
示例#6
0
def im_resize(maxwidth, path_in, path_out=None, quality=0):
    """Resize using ImageMagick.

    Use the ``magick`` program or ``convert`` on older versions. Return
    the output path of resized image.
    """
    path_out = path_out or temp_file_for(path_in)
    log.debug(u'artresizer: ImageMagick resizing {0} to {1}',
              util.displayable_path(path_in), util.displayable_path(path_out))

    # "-resize WIDTHx>" shrinks images with the width larger
    # than the given width while maintaining the aspect ratio
    # with regards to the height.
    cmd = ArtResizer.shared.im_convert_cmd + [
        util.syspath(path_in, prefix=False),
        '-resize',
        '{0}x>'.format(maxwidth),
    ]

    if quality > 0:
        cmd += ['-quality', '{0}'.format(quality)]

    cmd.append(util.syspath(path_out, prefix=False))

    try:
        util.command_output(cmd)
    except subprocess.CalledProcessError:
        log.warning(u'artresizer: IM convert failed for {0}',
                    util.displayable_path(path_in))
        return path_in

    return path_out
示例#7
0
文件: echonest.py 项目: ykumar6/beets
    def convert(self, source):
        """Converts an item in an unsupported media format to ogg.  Config
        pending.
        This is stolen from Jakob Schnitzers convert plugin.
        """
        fd, dest = tempfile.mkstemp(u'.ogg')
        os.close(fd)

        self._log.info(u'encoding {0} to {1}', util.displayable_path(source),
                       util.displayable_path(dest))

        opts = []
        for arg in CONVERT_COMMAND.split():
            arg = arg.encode('utf-8')
            opts.append(Template(arg).substitute(source=source, dest=dest))

        # Run the command.
        try:
            util.command_output(opts)
        except (OSError, subprocess.CalledProcessError) as exc:
            self._log.debug(u'encode failed: {0}', exc)
            util.remove(dest)
            return

        self._log.info(u'finished encoding {0}', util.displayable_path(source))
        return dest
示例#8
0
文件: echonest.py 项目: jck/beets
    def convert(self, source):
        """Converts an item in an unsupported media format to ogg.  Config
        pending.
        This is stolen from Jakob Schnitzers convert plugin.
        """
        fd, dest = tempfile.mkstemp(b'.ogg')
        os.close(fd)

        self._log.info(u'encoding {0} to {1}',
                       util.displayable_path(source),
                       util.displayable_path(dest))

        opts = []
        for arg in CONVERT_COMMAND.split():
            arg = arg.encode('utf-8')
            opts.append(Template(arg).substitute(source=source, dest=dest))

        # Run the command.
        try:
            util.command_output(opts)
        except (OSError, subprocess.CalledProcessError) as exc:
            self._log.debug(u'encode failed: {0}', exc)
            util.remove(dest)
            return

        self._log.info(u'finished encoding {0}', util.displayable_path(source))
        return dest
示例#9
0
def im_resize(maxwidth, path_in, path_out=None):
    """Resize using ImageMagick's ``convert`` tool.
    Return the output path of resized image.
    """
    path_out = path_out or temp_file_for(path_in)
    log.debug(u'artresizer: ImageMagick resizing {0} to {1}',
              util.displayable_path(path_in), util.displayable_path(path_out))

    # "-resize widthxheight>" shrinks images with dimension(s) larger
    # than the corresponding width and/or height dimension(s). The >
    # "only shrink" flag is prefixed by ^ escape char for Windows
    # compatibility.
    try:
        util.command_output([
            b'convert',
            util.syspath(path_in, prefix=False),
            b'-resize',
            b'{0}x^>'.format(maxwidth),
            util.syspath(path_out, prefix=False),
        ])
    except subprocess.CalledProcessError:
        log.warn(u'artresizer: IM convert failed for {0}',
                 util.displayable_path(path_in))
        return path_in
    return path_out
示例#10
0
def im_resize(maxwidth, path_in, path_out=None):
    """Resize using ImageMagick's ``convert`` tool.
    Return the output path of resized image.
    """
    path_out = path_out or temp_file_for(path_in)
    log.debug(
        u"artresizer: ImageMagick resizing {0} to {1}", util.displayable_path(path_in), util.displayable_path(path_out)
    )

    # "-resize widthxheight>" shrinks images with dimension(s) larger
    # than the corresponding width and/or height dimension(s). The >
    # "only shrink" flag is prefixed by ^ escape char for Windows
    # compatibility.
    try:
        util.command_output(
            [
                b"convert",
                util.syspath(path_in, prefix=False),
                b"-resize",
                b"{0}x^>".format(maxwidth),
                util.syspath(path_out, prefix=False),
            ]
        )
    except subprocess.CalledProcessError:
        log.warn(u"artresizer: IM convert failed for {0}", util.displayable_path(path_in))
        return path_in
    return path_out
示例#11
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('Encoding {0}', util.displayable_path(source))

        command = command.decode(arg_encoding(), 'surrogateescape')
        source = decode_commandline_path(source)
        dest = decode_commandline_path(dest)

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

        if pretend:
            self._log.info('{0}', ' '.join(ui.decargs(args)))
            return

        try:
            util.command_output(encode_cmd)
        except subprocess.CalledProcessError as exc:
            # Something went wrong (probably Ctrl+C), remove temporary files
            self._log.info('Encoding {0} failed. Cleaning up...',
                           util.displayable_path(source))
            self._log.debug('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(
                "convert: couldn't invoke '{}': {}".format(
                    ' '.join(ui.decargs(args)), exc
                )
            )

        if not quiet and not pretend:
            self._log.info('Finished encoding {0}',
                           util.displayable_path(source))
示例#12
0
文件: test_util.py 项目: JDLH/beets
    def test_command_output(self, mock_popen):
        def popen_fail(*args, **kwargs):
            m = Mock(returncode=1)
            m.communicate.return_value = u'foo', u'bar'
            return m

        mock_popen.side_effect = popen_fail
        with self.assertRaises(subprocess.CalledProcessError) as exc_context:
            util.command_output(['taga', '\xc3\xa9'])
        self.assertEqual(exc_context.exception.returncode, 1)
        self.assertEqual(exc_context.exception.cmd, 'taga \xc3\xa9')
示例#13
0
    def test_command_output(self, mock_popen):
        def popen_fail(*args, **kwargs):
            m = Mock(returncode=1)
            m.communicate.return_value = u'foo', u'bar'
            return m

        mock_popen.side_effect = popen_fail
        with self.assertRaises(subprocess.CalledProcessError) as exc_context:
            util.command_output([b"taga", b"\xc3\xa9"])
        self.assertEqual(exc_context.exception.returncode, 1)
        self.assertEqual(exc_context.exception.cmd, b"taga \xc3\xa9")
示例#14
0
    def test_command_output(self, mock_popen):
        def popen_fail(*args, **kwargs):
            m = Mock(returncode=1)
            m.communicate.return_value = None, None
            return m

        mock_popen.side_effect = popen_fail
        with self.assertRaises(subprocess.CalledProcessError) as exc_context:
            util.command_output([b"taga", b"\xc3\xa9"])
        self.assertEquals(exc_context.exception.returncode, 1)
        self.assertEquals(exc_context.exception.cmd, b"taga \xc3\xa9")
示例#15
0
文件: ipfs.py 项目: Ifiht/beets
    def ipfs_get_from_hash(self, lib, _hash):
        try:
            cmd = "ipfs get".split()
            cmd.append(_hash)
            util.command_output(cmd)
        except (OSError, subprocess.CalledProcessError) as err:
            self._log.error("Failed to get {0} from ipfs.\n{1}", _hash, err.output)
            return False

        self._log.info("Getting {0} from ipfs", _hash)
        imp = ui.commands.TerminalImportSession(lib, loghandler=None, query=None, paths=[_hash])
        imp.run()
        shutil.rmtree(_hash)
示例#16
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))
示例#17
0
文件: convert.py 项目: m-urban/beets
    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({
                b'source': source,
                b'dest': dest,
            })

        if pretend:
            self._log.info(' '.join(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}',
                            exc.cmd.decode('utf8', 'ignore'),
                            exc.returncode)
            util.remove(dest)
            util.prune_dirs(os.path.dirname(dest))
            raise
        except OSError as exc:
            raise ui.UserError(
                u"convert: could invoke '{0}': {1}".format(
                    ' '.join(args), exc
                )
            )

        if not quiet and not pretend:
            self._log.info(u'Finished encoding {0}',
                           util.displayable_path(source))
示例#18
0
def im_deinterlace(path_in, path_out=None):
    path_out = path_out or temp_file_for(path_in)

    cmd = ArtResizer.shared.im_convert_cmd + [
        util.syspath(path_in, prefix=False),
        '-interlace',
        'none',
        util.syspath(path_out, prefix=False),
    ]

    try:
        util.command_output(cmd)
        return path_out
    except subprocess.CalledProcessError:
        return path_in
示例#19
0
    def ipfs_get_from_hash(self, lib, _hash):
        try:
            cmd = "ipfs get".split()
            cmd.append(_hash)
            util.command_output(cmd)
        except (OSError, subprocess.CalledProcessError) as err:
            self._log.error('Failed to get {0} from ipfs.\n{1}',
                            _hash, err.output)
            return False

        self._log.info('Getting {0} from ipfs', _hash)
        imp = ui.commands.TerminalImportSession(lib, loghandler=None,
                                                query=None, paths=[_hash])
        imp.run()
        shutil.rmtree(_hash)
示例#20
0
文件: keyfinder.py 项目: JDLH/beets
    def find_key(self, items, write=False):
        overwrite = self.config['overwrite'].get(bool)
        bin = self.config['bin'].as_str()

        for item in items:
            if item['initial_key'] and not overwrite:
                continue

            try:
                output = util.command_output([bin, '-f',
                                              util.syspath(item.path)])
            except (subprocess.CalledProcessError, OSError) as exc:
                self._log.error(u'execution failed: {0}', exc)
                continue
            except UnicodeEncodeError:
                # Workaround for Python 2 Windows bug.
                # http://bugs.python.org/issue1759845
                self._log.error(u'execution failed for Unicode path: {0!r}',
                                item.path)
                continue

            key_raw = output.rsplit(None, 1)[-1]
            try:
                key = util.text_string(key_raw)
            except UnicodeDecodeError:
                self._log.error(u'output is invalid UTF-8')
                continue

            item['initial_key'] = key
            self._log.info(u'added computed initial key {0} for {1}',
                           key, util.displayable_path(item.path))

            if write:
                item.try_write()
            item.store()
示例#21
0
 def _checksum(self, item, prog):
     """Run external `prog` on file path associated with `item`, cache
     output as flexattr on a key that is the name of the program, and
     return the key, checksum tuple.
     """
     args = [p.format(file=item.path) for p in shlex.split(prog)]
     key = args[0]
     checksum = getattr(item, key, False)
     if not checksum:
         self._log.debug(
             u'key {0} on item {1} not cached:'
             u'computing checksum', key, displayable_path(item.path))
         try:
             checksum = command_output(args)
             setattr(item, key, checksum)
             item.store()
             self._log.debug(u'computed checksum for {0} using {1}',
                             item.title, key)
         except subprocess.CalledProcessError as e:
             self._log.debug(u'failed to checksum {0}: {1}',
                             displayable_path(item.path), e)
     else:
         self._log.debug(
             u'key {0} on item {1} cached:'
             u'not computing checksum', key, displayable_path(item.path))
     return key, checksum
示例#22
0
    def find_key(self, items, write=False):
        overwrite = self.config['overwrite'].get(bool)
        bin = util.bytestring_path(self.config['bin'].get(unicode))

        for item in items:
            if item['initial_key'] and not overwrite:
                continue

            try:
                output = util.command_output([bin, '-f', item.path])
            except (subprocess.CalledProcessError, OSError) as exc:
                self._log.error(u'execution failed: {0}', exc)
                continue

            key_raw = output.rsplit(None, 1)[-1]
            try:
                key = key_raw.decode('utf8')
            except UnicodeDecodeError:
                self._log.error(u'output is invalid UTF-8')
                continue

            item['initial_key'] = key
            self._log.info(u'added computed initial key {0} for {1}',
                           key, util.displayable_path(item.path))

            if write:
                item.try_write()
            item.store()
    def find_key(self, items, write=False):
        overwrite = self.config['overwrite'].get(bool)
        bin = self.config['bin'].as_str()

        for item in items:
            if item['initial_key'] and not overwrite:
                continue

            try:
                output = util.command_output(
                    [bin, '-f', util.syspath(item.path)])
            except (subprocess.CalledProcessError, OSError) as exc:
                self._log.error(u'execution failed: {0}', exc)
                continue
            except UnicodeEncodeError:
                # Workaround for Python 2 Windows bug.
                # http://bugs.python.org/issue1759845
                self._log.error(u'execution failed for Unicode path: {0!r}',
                                item.path)
                continue

            key_raw = output.rsplit(None, 1)[-1]
            try:
                key = util.text_string(key_raw)
            except UnicodeDecodeError:
                self._log.error(u'output is invalid UTF-8')
                continue

            item['initial_key'] = key
            self._log.info(u'added computed initial key {0} for {1}', key,
                           util.displayable_path(item.path))

            if write:
                item.try_write()
            item.store()
示例#24
0
    def _check_method(method=None):
        """A tuple indicating whether current method is available and its
        version. If no method is given, it returns a supported one.
        """
        # Guess available method
        if not method:
            for m in [IMAGEMAGICK, PIL]:
                _, version = ArtResizer._check_method(m)
                if version:
                    return (m, version)
            return (WEBPROXY, (0))

        if method == IMAGEMAGICK:

            # Try invoking ImageMagick's "convert".
            try:
                out = util.command_output(["identify", "--version"])

                if "imagemagick" in out.lower():
                    pattern = r".+ (\d+)\.(\d+)\.(\d+).*"
                    match = re.search(pattern, out)
                    if match:
                        return (IMAGEMAGICK, (int(match.group(1)), int(match.group(2)), int(match.group(3))))
                    return (IMAGEMAGICK, (0))

            except (subprocess.CalledProcessError, OSError):
                return (IMAGEMAGICK, None)

        if method == PIL:
            # Try importing PIL.
            try:
                __import__("PIL", fromlist=["Image"])
                return (PIL, (0))
            except ImportError:
                return (PIL, None)
示例#25
0
    def get_extractor_data(self, item):
        with tempfile.NamedTemporaryFile() as tmpfile:
            tmpfile.close()

            args = [self.extractor, util.syspath(item.path), tmpfile.name]
            try:
                util.command_output(args)
            except subprocess.CalledProcessError as exc:
                self._log.warning(u'{} "{}" "{}" exited with status {}',
                                  self.extractor,
                                  util.displayable_path(item.path),
                                  tmpfile.name, exc.returncode)
                return

            with open(tmpfile.name, 'rb') as tmp_file:
                return json.load(tmp_file)
示例#26
0
文件: artresizer.py 项目: msil/beets
    def version(cls):
        """Obtain and cache ImageMagick version.

        Raises `LocalBackendNotAvailableError` if not available.
        """
        if cls._version is None:
            for cmd_name, legacy in (('magick', False), ('convert', True)):
                try:
                    out = util.command_output([cmd_name, "--version"]).stdout
                except (subprocess.CalledProcessError, OSError) as exc:
                    log.debug('ImageMagick version check failed: {}', exc)
                    cls._version = _NOT_AVAILABLE
                else:
                    if b'imagemagick' in out.lower():
                        pattern = br".+ (\d+)\.(\d+)\.(\d+).*"
                        match = re.search(pattern, out)
                        if match:
                            cls._version = (int(match.group(1)),
                                            int(match.group(2)),
                                            int(match.group(3)))
                            cls._legacy = legacy

        if cls._version is _NOT_AVAILABLE:
            raise LocalBackendNotAvailableError()
        else:
            return cls._version
示例#27
0
 def _checksum(self, item, prog):
     """Run external `prog` on file path associated with `item`, cache
     output as flexattr on a key that is the name of the program, and
     return the key, checksum tuple.
     """
     args = [p.format(file=item.path) for p in shlex.split(prog)]
     key = args[0]
     checksum = getattr(item, key, False)
     if not checksum:
         self._log.debug(u'key {0} on item {1} not cached:'
                         u'computing checksum',
                         key, displayable_path(item.path))
         try:
             checksum = command_output(args)
             setattr(item, key, checksum)
             item.store()
             self._log.debug(u'computed checksum for {0} using {1}',
                             item.title, key)
         except subprocess.CalledProcessError as e:
             self._log.debug(u'failed to checksum {0}: {1}',
                             displayable_path(item.path), e)
     else:
         self._log.debug(u'key {0} on item {1} cached:'
                         u'not computing checksum',
                         key, displayable_path(item.path))
     return key, checksum
示例#28
0
def play_music(lib, opts, args):
    """Execute query, create temporary playlist and execute player
    command passing that playlist.
    """

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

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

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

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

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

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

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

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

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

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

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

    ui.print_(u'Playing {0} {1}.'.format(len(paths), item_type))
示例#29
0
    def find_key(self, items, write=False):
        overwrite = self.config['overwrite'].get(bool)
        bin = util.bytestring_path(self.config['bin'].get(unicode))

        for item in items:
            if item['initial_key'] and not overwrite:
                continue

            try:
                output = util.command_output([bin, '-f', item.path])
            except (subprocess.CalledProcessError, OSError) as exc:
                self._log.error(u'execution failed: {0}', exc)
                continue

            key_raw = output.rsplit(None, 1)[-1]
            try:
                key = key_raw.decode('utf8')
            except UnicodeDecodeError:
                self._log.error(u'output is invalid UTF-8')
                continue

            item['initial_key'] = key
            self._log.info(u'added computed initial key {0} for {1}',
                           key, util.displayable_path(item.path))

            if write:
                item.try_write()
            item.store()
示例#30
0
文件: artresizer.py 项目: msil/beets
    def deinterlace(self, path_in, path_out=None):
        path_out = path_out or temp_file_for(path_in)

        cmd = self.convert_cmd + [
            syspath(path_in, prefix=False),
            '-interlace',
            'none',
            syspath(path_out, prefix=False),
        ]

        try:
            util.command_output(cmd)
            return path_out
        except subprocess.CalledProcessError:
            # FIXME: Should probably issue a warning?
            return path_in
示例#31
0
def encode(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.
    """
    quiet = config['convert']['quiet'].get()

    if not quiet and not pretend:
        log.info(u'Encoding {0}'.format(util.displayable_path(source)))

    if os.name == 'nt':
		command = Template(command).safe_substitute({
			'source': '"' + source + '"',
			'dest':   '"' + dest + '"',
		})
	else:
		command = Template(command).safe_substitute({
			'source': pipes.quote(source),
			'dest':   pipes.quote(dest),
		})

    log.debug(u'convert: executing: {0}'
              .format(util.displayable_path(command)))

    if pretend:
        log.info(command)
        return

    try:
        util.command_output(command, shell=True)
    except subprocess.CalledProcessError:
        # Something went wrong (probably Ctrl+C), remove temporary files
        log.info(u'Encoding {0} failed. Cleaning up...'
                 .format(util.displayable_path(source)))
        util.remove(dest)
        util.prune_dirs(os.path.dirname(dest))
        raise
    except OSError as exc:
        raise ui.UserError(
            u"convert: could invoke '{0}': {0}".format(command, exc)
        )

    if not quiet and not pretend:
        log.info(u'Finished encoding {0}'.format(
            util.displayable_path(source))
        )
示例#32
0
def encode(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.
    """
    quiet = config['convert']['quiet'].get()

    if not quiet and not pretend:
        log.info(u'Encoding {0}'.format(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:
        log.info(' '.join(args))
        return

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

    if not quiet and not pretend:
        log.info(u'Finished encoding {0}'.format(
            util.displayable_path(source))
        )
示例#33
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))
示例#34
0
文件: artresizer.py 项目: msil/beets
    def get_format(self, filepath):
        cmd = self.identify_cmd + ['-format', '%[magick]', syspath(filepath)]

        try:
            return util.command_output(cmd).stdout
        except subprocess.CalledProcessError:
            # FIXME: Should probably issue a warning?
            return None
示例#35
0
文件: artresizer.py 项目: msil/beets
    def resize(self,
               maxwidth,
               path_in,
               path_out=None,
               quality=0,
               max_filesize=0):
        """Resize using ImageMagick.

        Use the ``magick`` program or ``convert`` on older versions. Return
        the output path of resized image.
        """
        path_out = path_out or temp_file_for(path_in)
        log.debug('artresizer: ImageMagick resizing {0} to {1}',
                  displayable_path(path_in), displayable_path(path_out))

        # "-resize WIDTHx>" shrinks images with the width larger
        # than the given width while maintaining the aspect ratio
        # with regards to the height.
        # ImageMagick already seems to default to no interlace, but we include
        # it here for the sake of explicitness.
        cmd = self.convert_cmd + [
            syspath(path_in, prefix=False),
            '-resize',
            f'{maxwidth}x>',
            '-interlace',
            'none',
        ]

        if quality > 0:
            cmd += ['-quality', f'{quality}']

        # "-define jpeg:extent=SIZEb" sets the target filesize for imagemagick
        # to SIZE in bytes.
        if max_filesize > 0:
            cmd += ['-define', f'jpeg:extent={max_filesize}b']

        cmd.append(syspath(path_out, prefix=False))

        try:
            util.command_output(cmd)
        except subprocess.CalledProcessError:
            log.warning('artresizer: IM convert failed for {0}',
                        displayable_path(path_in))
            return path_in

        return path_out
示例#36
0
def im_get_format(filepath):
    cmd = ArtResizer.shared.im_identify_cmd + [
        '-format', '%[magick]', util.syspath(filepath)
    ]

    try:
        return util.command_output(cmd).stdout
    except subprocess.CalledProcessError:
        return None
示例#37
0
def call(args):
    """Execute the command and return its output or raise a
    ReplayGainError on failure.
    """
    try:
        return command_output(args)
    except subprocess.CalledProcessError as e:
        raise ReplayGainError("{0} exited with status {1}".format(
            args[0], e.returncode))
示例#38
0
def call(args):
    """Execute the command indicated by `args` (a list of strings) and
    return the command's output. The stderr stream is ignored. If the
    command exits abnormally, a ArtResizerError is raised.
    """
    try:
        return util.command_output(args)
    except subprocess.CalledProcessError as e:
        raise ArtResizerError("{0} exited with status {1}".format(
            args[0], e.returncode))
示例#39
0
def im_getsize(path_in):
    try:
        out = util.command_output([b"identify", b"-format", b"%w %h", util.syspath(path_in)])
    except subprocess.CalledProcessError:
        log.warn("IM cannot compute size of {0}", util.displayable_path(path_in))
        return
    try:
        return tuple(map(int, out.split(b" ")))
    except IndexError:
        log.warn("Could not understand IM output: {0!r}", out)
示例#40
0
文件: replaygain.py 项目: flz/beets
def call(args):
    """Execute the command and return its output or raise a
    ReplayGainError on failure.
    """
    try:
        return command_output(args)
    except subprocess.CalledProcessError as e:
        raise ReplayGainError(
            "{0} exited with status {1}".format(args[0], e.returncode)
        )
示例#41
0
def call(args):
    """Execute the command and return its output.

    Raise a AnalysisABSubmitError on failure.
    """
    try:
        return util.command_output(args)
    except subprocess.CalledProcessError as e:
        raise ABSubmitError(u'{0} exited with status {1}'.format(
            args[0], e.returncode))
示例#42
0
def encode(source, dest):
    """Encode ``source`` to ``dest`` using the command from ``get_format()``.

    Raises an ``ui.UserError`` if the command was not found and a
    ``subprocess.CalledProcessError`` if the command exited with a
    non-zero status code.
    """
    quiet = config['convert']['quiet'].get()

    if not quiet:
        log.info(u'Started encoding {0}'.format(util.displayable_path(source)))

    command, _ = get_format()
    opts = []
    for arg in command:
        opts.append(Template(arg).safe_substitute({
            'source': source,
            'dest':   dest,
        }))

    log.debug(u'convert: executing: {0}'.format(
        u' '.join(pipes.quote(o.decode('utf8', 'ignore')) for o in opts)
    ))

    try:
        util.command_output(opts)
    except subprocess.CalledProcessError:
        # Something went wrong (probably Ctrl+C), remove temporary files
        log.info(u'Encoding {0} failed. Cleaning up...'
                 .format(util.displayable_path(source)))
        util.remove(dest)
        util.prune_dirs(os.path.dirname(dest))
        raise
    except OSError as exc:
        raise ui.UserError(
            u'convert: could invoke ffmpeg: {0}'.format(exc)
        )

    if not quiet:
        log.info(u'Finished encoding {0}'.format(
            util.displayable_path(source))
        )
示例#43
0
def call(args):
    """Execute the command indicated by `args` (a list of strings) and
    return the command's output. The stderr stream is ignored. If the
    command exits abnormally, a ArtResizerError is raised.
    """
    try:
        return util.command_output(args)
    except subprocess.CalledProcessError as e:
        raise ArtResizerError(
            "{0} exited with status {1}".format(args[0], e.returncode)
        )
示例#44
0
文件: absubmit.py 项目: arogl/beets
def call(args):
    """Execute the command and return its output.

    Raise a AnalysisABSubmitError on failure.
    """
    try:
        return util.command_output(args)
    except subprocess.CalledProcessError as e:
        raise ABSubmitError(
            u'{0} exited with status {1}'.format(args[0], e.returncode)
        )
示例#45
0
def encode(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.
    """
    quiet = config['convert']['quiet'].get()

    if not quiet and not pretend:
        log.info(u'Encoding {0}'.format(util.displayable_path(source)))

    command = Template(command).safe_substitute({
        'source': pipes.quote(source),
        'dest':   pipes.quote(dest),
    })

    log.debug(u'convert: executing: {0}'
              .format(util.displayable_path(command)))

    if pretend:
        log.info(command)
        return

    try:
        util.command_output(command, shell=True)
    except subprocess.CalledProcessError:
        # Something went wrong (probably Ctrl+C), remove temporary files
        log.info(u'Encoding {0} failed. Cleaning up...'
                 .format(util.displayable_path(source)))
        util.remove(dest)
        util.prune_dirs(os.path.dirname(dest))
        raise
    except OSError as exc:
        raise ui.UserError(
            u"convert: could invoke '{0}': {0}".format(command, exc)
        )

    if not quiet and not pretend:
        log.info(u'Finished encoding {0}'.format(
            util.displayable_path(source))
        )
示例#46
0
文件: ipfs.py 项目: DArtagan/beets
 def ipfs_publish(self, lib):
     with tempfile.NamedTemporaryFile() as tmp:
         self.ipfs_added_albums(lib, tmp.name)
         try:
             cmd = "ipfs add -q ".split()
             cmd.append(tmp.name)
             output = util.command_output(cmd)
         except (OSError, subprocess.CalledProcessError) as err:
             msg = "Failed to publish library. Error: {0}".format(err)
             self._log.error(msg)
             return False
         self._log.info("hash of library: {0}", output)
示例#47
0
def im_getsize(path_in):
    try:
        out = util.command_output(['identify', '-format', '%w %h',
                                   util.syspath(path_in)])
    except subprocess.CalledProcessError:
        log.warn(u'IM cannot compute size of {0}',
                 util.displayable_path(path_in))
        return
    try:
        return tuple(map(int, out.split(b' ')))
    except IndexError:
        log.warn(u'Could not understand IM output: {0!r}', out)
示例#48
0
 def ipfs_publish(self, lib):
     with tempfile.NamedTemporaryFile() as tmp:
         self.ipfs_added_albums(lib, tmp.name)
         try:
             cmd = "ipfs add -q ".split()
             cmd.append(tmp.name)
             output = util.command_output(cmd)
         except (OSError, subprocess.CalledProcessError) as err:
             msg = "Failed to publish library. Error: {0}".format(err)
             self._log.error(msg)
             return False
         self._log.info("hash of library: {0}", output)
def im_resize(maxwidth, path_in, path_out=None):
    """Resize using ImageMagick's ``convert`` tool.
    Return the output path of resized image.
    """
    path_out = path_out or temp_file_for(path_in)
    log.debug(u'artresizer: ImageMagick resizing {0} to {1}',
              util.displayable_path(path_in), util.displayable_path(path_out))

    # "-resize WIDTHx>" shrinks images with the width larger
    # than the given width while maintaining the aspect ratio
    # with regards to the height.
    try:
        util.command_output([
            'convert', util.syspath(path_in, prefix=False),
            '-resize', '{0}x>'.format(maxwidth),
            util.syspath(path_out, prefix=False),
        ])
    except subprocess.CalledProcessError:
        log.warning(u'artresizer: IM convert failed for {0}',
                    util.displayable_path(path_in))
        return path_in
    return path_out
示例#50
0
文件: artresizer.py 项目: tima/beets
def im_getsize(path_in):
    try:
        out = util.command_output(
            [b'identify', b'-format', b'%w %h',
             util.syspath(path_in)])
    except subprocess.CalledProcessError:
        log.warn(u'IM cannot compute size of {0}',
                 util.displayable_path(path_in))
        return
    try:
        return tuple(map(int, out.split(b' ')))
    except IndexError:
        log.warn(u'Could not understand IM output: {0!r}', out)
示例#51
0
def call(args):
    """Execute the command and return its output or raise a
    ReplayGainError on failure.
    """
    try:
        return command_output(args)
    except subprocess.CalledProcessError as e:
        raise ReplayGainError(u"{0} exited with status {1}".format(args[0], e.returncode))
    except UnicodeEncodeError:
        # Due to a bug in Python 2's subprocess on Windows, Unicode
        # filenames can fail to encode on that platform. See:
        # https://github.com/google-code-export/beets/issues/499
        raise ReplayGainError(u"argument encoding failed")
示例#52
0
    def ipfs_import(self, lib, args):
        _hash = args[0]
        if len(args) > 1:
            lib_name = args[1]
        else:
            lib_name = _hash
        lib_root = os.path.dirname(lib.path)
        remote_libs = os.path.join(lib_root, b"remotes")
        if not os.path.exists(remote_libs):
            try:
                os.makedirs(remote_libs)
            except OSError as e:
                msg = f"Could not create {remote_libs}. Error: {e}"
                self._log.error(msg)
                return False
        path = os.path.join(remote_libs, lib_name.encode() + b".db")
        if not os.path.exists(path):
            cmd = f"ipfs get {_hash} -o".split()
            cmd.append(path)
            try:
                util.command_output(cmd)
            except (OSError, subprocess.CalledProcessError):
                self._log.error(f"Could not import {_hash}")
                return False

        # add all albums from remotes into a combined library
        jpath = os.path.join(remote_libs, b"joined.db")
        jlib = library.Library(jpath)
        nlib = library.Library(path)
        for album in nlib.albums():
            if not self.already_added(album, jlib):
                new_album = []
                for item in album.items():
                    item.id = None
                    new_album.append(item)
                added_album = jlib.add_album(new_album)
                added_album.ipfs = album.ipfs
                added_album.store()
示例#53
0
文件: ipfs.py 项目: wickism/beets
    def ipfs_import(self, lib, args):
        _hash = args[0]
        if len(args) > 1:
            lib_name = args[1]
        else:
            lib_name = _hash
        lib_root = os.path.dirname(lib.path)
        remote_libs = lib_root + "/remotes"
        if not os.path.exists(remote_libs):
            try:
                os.makedirs(remote_libs)
            except OSError as e:
                msg = "Could not create {0}. Error: {1}".format(remote_libs, e)
                self._log.error(msg)
                return False
        path = remote_libs + "/" + lib_name + ".db"
        if not os.path.exists(path):
            cmd = "ipfs get {0} -o".format(_hash).split()
            cmd.append(path)
            try:
                util.command_output(cmd)
            except (OSError, subprocess.CalledProcessError):
                self._log.error("Could not import {0}".format(_hash))
                return False

        # add all albums from remotes into a combined library
        jpath = remote_libs + "/joined.db"
        jlib = library.Library(jpath)
        nlib = library.Library(path)
        for album in nlib.albums():
            if not self.already_added(album, jlib):
                new_album = []
                for item in album.items():
                    item.id = None
                    new_album.append(item)
                added_album = jlib.add_album(new_album)
                added_album.ipfs = album.ipfs
                added_album.store()
示例#54
0
文件: ipfs.py 项目: DArtagan/beets
    def ipfs_import(self, lib, args):
        _hash = args[0]
        if len(args) > 1:
            lib_name = args[1]
        else:
            lib_name = _hash
        lib_root = os.path.dirname(lib.path)
        remote_libs = lib_root + "/remotes"
        if not os.path.exists(remote_libs):
            try:
                os.makedirs(remote_libs)
            except OSError as e:
                msg = "Could not create {0}. Error: {1}".format(remote_libs, e)
                self._log.error(msg)
                return False
        path = remote_libs + "/" + lib_name + ".db"
        if not os.path.exists(path):
            cmd = "ipfs get {0} -o".format(_hash).split()
            cmd.append(path)
            try:
                util.command_output(cmd)
            except (OSError, subprocess.CalledProcessError):
                self._log.error("Could not import {0}".format(_hash))
                return False

        # add all albums from remotes into a combined library
        jpath = remote_libs + "/joined.db"
        jlib = library.Library(jpath)
        nlib = library.Library(path)
        for album in nlib.albums():
            if not self.already_added(album, jlib):
                new_album = []
                for item in album.items():
                    item.id = None
                    new_album.append(item)
                added_album = jlib.add_album(new_album)
                added_album.ipfs = album.ipfs
                added_album.store()
示例#55
0
def has_IM():
    """Return Image Magick version or None if it is unavailable
    Try invoking ImageMagick's "convert"."""
    try:
        out = util.command_output([b"identify", b"--version"])

        if "imagemagick" in out.lower():
            pattern = r".+ (\d+)\.(\d+)\.(\d+).*"
            match = re.search(pattern, out)
            if match:
                return (int(match.group(1)), int(match.group(2)), int(match.group(3)))
            return (0,)

    except (subprocess.CalledProcessError, OSError):
        return None
示例#56
0
def im_getsize(path_in):
    cmd = [b"identify", b"-format", b"%w %h", util.syspath(path_in)]
    try:
        out = util.command_output(cmd)
    except subprocess.CalledProcessError as exc:
        log.warn(
            "ImageMagick invocation failed when " "getting size with command {}: {}: cannot compute size of {0}",
            cmd,
            exc,
        )
        return
    try:
        return tuple(map(int, out.split(b" ")))
    except IndexError:
        log.warn("Could not understand IM output: {0!r}", out)
示例#57
0
def im_getsize(path_in):
    cmd = [b'identify', b'-format', b'%w %h',
           util.syspath(path_in, prefix=False)]
    try:
        out = util.command_output(cmd)
    except subprocess.CalledProcessError as exc:
        log.warn(u'ImageMagick size query failed')
        log.debug(
            u'`convert` exited with (status {}) when '
            u'getting size with command {}:\n{}',
            exc.returncode, cmd, exc.output.strip()
        )
        return
    try:
        return tuple(map(int, out.split(b' ')))
    except IndexError:
        log.warn(u'Could not understand IM output: {0!r}', out)