コード例 #1
0
ファイル: prefixes.py プロジェクト: hile/soundforest
    class TreePrefixInstance(list):

        def __init__(self):
            self.log = SoundforestLogger().default_stream
            self.db = ConfigDB()

            common_prefixes = set(DEFAULT_PATHS + [prefix.path for prefix in self.db.tree_prefixes])

            for path in common_prefixes:
                for name, codec in self.db.codec_configuration.items():
                    prefix_path = os.path.join(path, name)
                    prefix = MusicTreePrefix(prefix_path, [codec.name] + codec.extensions)
                    self.add_prefix(prefix)

                if 'm4a' in self.db.codec_configuration.keys():
                    prefix_path = os.path.join(path, 'm4a')
                    prefix = MusicTreePrefix(prefix_path, self.db.codec_configuration.extensions('m4a'))
                    self.add_prefix(prefix)

            itunes_prefix = MusicTreePrefix(ITUNES_MUSIC, self.db.codec_configuration.extensions('m4a'))
            self.add_prefix(itunes_prefix)
            self.load_user_config()

        def load_user_config(self):
            if not os.path.isfile(USER_PATH_CONFIG):
                return

            try:
                with open(USER_PATH_CONFIG, 'r') as config:

                    user_codecs = {}
                    for line in config:

                        try:
                            if line.strip() == '' or line[:1] == '#':
                                continue
                            (codec_name, paths) = [x.strip() for x in line.split('=', 1)]
                            paths = [x.strip() for x in paths.split(',')]
                        except ValueError:
                            self.log.debug('Error parsing line: {}'.format(line))
                            continue

                        user_codecs[codec_name] = paths

                    for codec_name in reversed(sorted(user_codecs.keys())):
                        paths = user_codecs[codec_name]

                        if codec_name == 'itunes':
                            codec = match_codec('m4a')
                        else:
                            codec = match_codec(codec_name)

                        if not codec:
                            continue

                        for path in reversed(paths):
                            prefix = MusicTreePrefix(path, self.db.codec_configuration.extensions('aac'))

                            if codec_name == 'itunes':
                                self.add_prefix(prefix, prepend=False)
                            else:
                                self.add_prefix(prefix, prepend=True)

            except IOError as e:
                raise PrefixError('Error reading {}: {}'.format(
                    USER_PATH_CONFIG,
                    e,
                ))

        def index(self, prefix):
            if not isinstance(prefix, MusicTreePrefix):
                raise PrefixError('Prefix must be MusicTreePrefix instance')

            for index, existing in enumerate(self):
                if prefix.realpath == existing.realpath:
                    return index

            raise IndexError('Prefix is not registered')

        def add_prefix(self, prefix, extensions=[], prepend=False):
            if isinstance(prefix, str):
                prefix = MusicTreePrefix(prefix, extensions)

            if not isinstance(prefix, MusicTreePrefix):
                raise PrefixError('prefix must be string or MusicTreePrefix instance')

            try:
                index = self.index(prefix)
                if prepend and index != 0:
                    prefix = self.pop(index)
                    self.insert(0, prefix)

            except IndexError:
                if prepend:
                    self.insert(0, prefix)
                else:
                    self.append(prefix)

            return prefix

        def match_extension(self, extension, match_existing=False):
            for prefix in self:
                if match_existing and not os.path.isdir(prefix.path):
                    continue

                if prefix.match_extension(extension):
                    return prefix

            return None

        def match(self, path, match_existing=False):
            for prefix in self:

                if match_existing and not os.path.isdir(prefix.path):
                    continue

                if prefix.match(path):
                    return prefix

            return None

        def relative_path(self, path):
            prefix = self.match(path)
            if not prefix:
                return path

            return prefix.relative_path(path)
コード例 #2
0
class AudioFileFormat(object):
    """AudioFileFormat

    Common file format wrapper for various codecs

    """

    def __init__(self, path):
        self.log =  SoundforestLogger().default_stream
        self.path = path_string(path)
        self.codec = None
        self.description = None
        self.is_metadata = False

        self.codec = match_codec(path)
        if self.codec is not None:
            self.description = self.codec.description.lower()

        else:
            m = match_metadata(path)
            if m:
                self.is_metadata = True
                self.description = m.description.lower()

            elif os.path.isdir(path):
                self.description = 'unknown directory'

            else:
                self.description = 'unknown file format'

    def __repr__(self):
        return '{0} {1}'.format(self.codec, self.path)

    @property
    def directory(self):
        return os.path.dirname(self.path)

    @property
    def filename(self):
        return os.path.basename(self.path)

    @property
    def extension(self):
        return os.path.splitext(self.path)[1][1:]

    @property
    def size(self):
        if not self.path.isfile:
            return None
        return os.stat(self.path).st_size

    @property
    def ctime(self):
        if not self.path.isfile:
            return None
        return os.stat(self.path).st_ctime

    @property
    def mtime(self):
        if not self.path.isfile:
            return None
        return os.stat(self.path).st_mtime

    def get_temporary_file(self, dir=SOUNDFOREST_CACHE_DIR, prefix='tmp', suffix=''):
        if not os.path.isdir(dir):
            try:
                os.makedirs(dir)
            except IOError as e:
                raise SoundforestError('Error creating directory {0}: {1}'.format(SOUNDFOREST_CACHE_DIR, e))
            except OSError as e:
                raise SoundforestError('Error creating directory {0}: {1}'.format(SOUNDFOREST_CACHE_DIR, e))

        return tempfile.mktemp(dir=dir, prefix=prefix, suffix=suffix)

    def get_tag_parser(self):
        if self.codec is None:
            return None

        if self.codec.name in TAG_PARSERS.keys():
            classpath = TAG_PARSERS[self.codec.name]
        else:
            try:
                classpath = TAG_PARSERS[TAG_EXTENSION_ALIASES[self.codec.name]]
            except KeyError:
                return None

        module_path = '.'.join(classpath.split('.')[:-1])
        class_name = classpath.split('.')[-1]
        m = __import__(module_path, globals(), fromlist=[class_name])

        return getattr(m, class_name)

    def get_available_encoders(self):
        if self.codec is None or not self.codec.encoders:
            return []

        return filter_available_command_list(self.codec.encoders)

    def get_available_decoders(self):
        if self.codec is None or not self.codec.decoders:
            return []

        return filter_available_command_list(self.codec.decoders)

    def get_available_testers(self):
        if self.codec is None or not self.codec.testers:
            return []

        return filter_available_command_list(self.codec.testers)

    def execute(self, args):
        self.log.debug('running: {0}'.format(' '.join(args)))
        p = Popen(args, stdin=PIPE, stdout=PIPE, stderr=PIPE)
        (stdout, stderr) = p.communicate()

        if stdout:
            self.log.debug('output:\n{0}'.format(stdout))
        if stderr:
            self.log.debug('errors:\n{0}'.format(stderr))

        return p.returncode, stdout, stderr
コード例 #3
0
    class TreePrefixInstance(list):

        def __init__(self):
            self.log = SoundforestLogger().default_stream
            list.__init__(self)
            self.db = ConfigDB()

            common_prefixes = set(DEFAULT_PATHS + [prefix.path for prefix in self.db.prefixes])

            for path in common_prefixes:
                for name, codec in self.db.codecs.items():
                    prefix_path = os.path.join(path, name)
                    prefix = MusicTreePrefix(prefix_path, [codec.name] + codec.extensions)
                    self.register_prefix(prefix)

                if 'm4a' in self.db.codecs.keys():
                    prefix_path = os.path.join(path, 'm4a')
                    prefix = MusicTreePrefix(prefix_path, self.db.codecs.extensions('m4a'))
                    self.register_prefix(prefix)

            itunes_prefix = MusicTreePrefix(ITUNES_MUSIC, self.db.codecs.extensions('m4a'))
            self.register_prefix(itunes_prefix)
            self.load_user_config()

        def load_user_config(self):
            if not os.path.isfile(USER_PATH_CONFIG):
                return

            try:
                with open(USER_PATH_CONFIG, 'r') as config:

                    user_codecs = {}
                    for line in config:

                        try:
                            if line.strip() == '' or line[:1] == '#':
                                continue
                            (codec_name, paths) = [x.strip() for x in line.split('=', 1)]
                            paths = [x.strip() for x in paths.split(',')]
                        except ValueError:
                            self.log.debug('Error parsing line: %s' % line)
                            continue

                        user_codecs[codec_name] = paths

                    for codec_name in reversed(sorted(user_codecs.keys())):
                        paths = user_codecs[codec_name]

                        if codec_name == 'itunes':
                            codec = match_codec('m4a')
                        else:
                            codec = match_codec(codec_name)

                        if not codec:
                            continue

                        for path in reversed(paths):
                            prefix = MusicTreePrefix(path, self.db.codecs.extensions('aac'))

                            if codec_name == 'itunes':
                                self.register_prefix(prefix, prepend=False)
                            else:
                                self.register_prefix(prefix, prepend=True)

            except IOError, (ecode, emsg):
                raise PrefixError('Error reading %s: %s' % (USER_PATH_CONFIG, emsg))