コード例 #1
0
    def replace_path(self, config_path, path):
        if config_path in self.replacements:
            replacements = self.replacements[config_path]
        else:
            replacements = self.replacements[config_path] = get_replacements(config_path)

        return util.sanitize_path(path, replacements)
コード例 #2
0
ファイル: test_db.py プロジェクト: sbuser/beets
 def test_sanitize_windows_replaces_illegal_chars(self):
     p = util.sanitize_path(':*?"<>|', ntpath)
     self.assertFalse(":" in p)
     self.assertFalse("*" in p)
     self.assertFalse("?" in p)
     self.assertFalse('"' in p)
     self.assertFalse("<" in p)
     self.assertFalse(">" in p)
     self.assertFalse("|" in p)
コード例 #3
0
ファイル: test_db.py プロジェクト: jenzie/beets
 def test_sanitize_windows_replaces_illegal_chars(self):
     p = util.sanitize_path(u':*?"<>|', ntpath)
     self.assertFalse(':' in p)
     self.assertFalse('*' in p)
     self.assertFalse('?' in p)
     self.assertFalse('"' in p)
     self.assertFalse('<' in p)
     self.assertFalse('>' in p)
     self.assertFalse('|' in p)
コード例 #4
0
ファイル: test_db.py プロジェクト: Bitdemon/beets
 def test_sanitize_windows_replaces_illegal_chars(self):
     p = util.sanitize_path(u':*?"<>|', ntpath)
     self.assertFalse(':' in p)
     self.assertFalse('*' in p)
     self.assertFalse('?' in p)
     self.assertFalse('"' in p)
     self.assertFalse('<' in p)
     self.assertFalse('>' in p)
     self.assertFalse('|' in p)
コード例 #5
0
ファイル: test_library.py プロジェクト: Brainversation/beets
 def test_sanitize_windows_replaces_illegal_chars(self):
     with _common.platform_windows():
         p = util.sanitize_path(u':*?"<>|')
     self.assertFalse(':' in p)
     self.assertFalse('*' in p)
     self.assertFalse('?' in p)
     self.assertFalse('"' in p)
     self.assertFalse('<' in p)
     self.assertFalse('>' in p)
     self.assertFalse('|' in p)
コード例 #6
0
 def test_sanitize_windows_replaces_illegal_chars(self):
     with _common.platform_windows():
         p = util.sanitize_path(u':*?"<>|')
     self.assertFalse(u':' in p)
     self.assertFalse(u'*' in p)
     self.assertFalse(u'?' in p)
     self.assertFalse(u'"' in p)
     self.assertFalse(u'<' in p)
     self.assertFalse(u'>' in p)
     self.assertFalse(u'|' in p)
コード例 #7
0
ファイル: fetchartist.py プロジェクト: fr3akout/fetchartist
    def _create_cover_path(self, item):
        if item.singleton:
            template = self._singleton_template
        else:
            template = self._default_template

        evaluated_template = item.evaluate_template(template)
        cover_name = self._get_cover_name(item)
        path = os.path.join(evaluated_template, cover_name)
        return os.path.join(self._library_path, beetsutil.sanitize_path(path))
コード例 #8
0
    def sub_path(self, path, pattern, repl=''):
        if pattern in self.patterns:
            pattern = self.patterns[pattern]
        else:
            pattern = self.patterns[pattern] = re.compile(pattern)

        try:
            return util.sanitize_path(path, [(pattern, repl)])
        except re.error as exc:
            raise UserError(u'%sub_path: error compiling regex `{0}`: {1}'.format(pattern, str(exc)))
コード例 #9
0
    def _create_cover_path(self, item):
        if item.singleton:
            template = self._singleton_template
        else:
            template = self._default_template

        evaluated_template = item.evaluate_template(template)
        cover_name = self._get_cover_name(item)
        path = os.path.join(evaluated_template, cover_name)

        return os.path.join(self._library_path, beetsutil.sanitize_path(path))
コード例 #10
0
ファイル: replacefunc.py プロジェクト: kergoth/beets-kergoth
    def replace(self, field, path):
        if field in self.replacements:
            replacements = self.replacements[field]
        else:
            try:
                replacements = self.replacements[field] = get_replacements(
                    self.config[field])
            except confuse.ConfigError as exc:
                raise UserError(
                    f"Configuration error in `{self.name}.{field}`: {exc}")

        return util.sanitize_path(path, replacements)
コード例 #11
0
ファイル: smartplaylist.py プロジェクト: adamjakab/Beets
    def update_playlists(self, lib):
        self._log.info("Updating {0} smart playlists...",
                       len(self._matched_playlists))

        playlist_dir = self.config['playlist_dir'].as_filename()
        playlist_dir = bytestring_path(playlist_dir)
        relative_to = self.config['relative_to'].get()
        if relative_to:
            relative_to = normpath(relative_to)

        # Maps playlist filenames to lists of track filenames.
        m3us = {}

        for playlist in self._matched_playlists:
            name, (query, q_sort), (album_query, a_q_sort) = playlist
            self._log.debug("Creating playlist {0}", name)
            items = []

            if query:
                items.extend(lib.items(query, q_sort))
            if album_query:
                for album in lib.albums(album_query, a_q_sort):
                    items.extend(album.items())

            # As we allow tags in the m3u names, we'll need to iterate through
            # the items and generate the correct m3u file names.
            for item in items:
                m3u_name = item.evaluate_template(name, True)
                m3u_name = sanitize_path(m3u_name, lib.replacements)
                if m3u_name not in m3us:
                    m3us[m3u_name] = []
                item_path = item.path
                if relative_to:
                    item_path = os.path.relpath(item.path, relative_to)
                if item_path not in m3us[m3u_name]:
                    m3us[m3u_name].append(item_path)

        prefix = bytestring_path(self.config['prefix'].as_str())
        # Write all of the accumulated track lists to files.
        for m3u in m3us:
            m3u_path = normpath(
                os.path.join(playlist_dir, bytestring_path(m3u)))
            mkdirall(m3u_path)
            with open(syspath(m3u_path), 'wb') as f:
                for path in m3us[m3u]:
                    if self.config['forward_slash'].get():
                        path = path_as_posix(path)
                    if self.config['urlencode']:
                        path = bytestring_path(pathname2url(path))
                    f.write(prefix + path + b'\n')

        self._log.info("{0} playlists updated", len(self._matched_playlists))
コード例 #12
0
ファイル: tagging.py プロジェクト: 8b00001000/libpth
def directory_name(release):
    '''
    Returns the proper directory name for a Release.
    '''
    artist = textwrap.shorten(release.album_artist, width=50, placeholder='_')
    album = textwrap.shorten(release.title, width=40, placeholder='_')
    year = release.year
    format_info = release.format
    if release.medium != 'CD':
        format_info = release.medium + ' ' + format_info
    path = ALBUM_TEMPLATE.substitute(**locals())
    if release.catalog_number:
        path += ' {' + release.catalog_number + '}'
    path = path.replace('/', '_').replace('\\', '_')
    path = sanitize_path(path)
    return path
コード例 #13
0
ファイル: smartplaylist.py プロジェクト: JDLH/beets
    def update_playlists(self, lib):
        self._log.info(u"Updating {0} smart playlists...",
                       len(self._matched_playlists))

        playlist_dir = self.config['playlist_dir'].as_filename()
        playlist_dir = bytestring_path(playlist_dir)
        relative_to = self.config['relative_to'].get()
        if relative_to:
            relative_to = normpath(relative_to)

        # Maps playlist filenames to lists of track filenames.
        m3us = {}

        for playlist in self._matched_playlists:
            name, (query, q_sort), (album_query, a_q_sort) = playlist
            self._log.debug(u"Creating playlist {0}", name)
            items = []

            if query:
                items.extend(lib.items(query, q_sort))
            if album_query:
                for album in lib.albums(album_query, a_q_sort):
                    items.extend(album.items())

            # As we allow tags in the m3u names, we'll need to iterate through
            # the items and generate the correct m3u file names.
            for item in items:
                m3u_name = item.evaluate_template(name, True)
                m3u_name = sanitize_path(m3u_name, lib.replacements)
                if m3u_name not in m3us:
                    m3us[m3u_name] = []
                item_path = item.path
                if relative_to:
                    item_path = os.path.relpath(item.path, relative_to)
                if item_path not in m3us[m3u_name]:
                    m3us[m3u_name].append(item_path)

        # Write all of the accumulated track lists to files.
        for m3u in m3us:
            m3u_path = normpath(os.path.join(playlist_dir,
                                bytestring_path(m3u)))
            mkdirall(m3u_path)
            with open(syspath(m3u_path), 'wb') as f:
                for path in m3us[m3u]:
                    f.write(path + b'\n')

        self._log.info(u"{0} playlists updated", len(self._matched_playlists))
コード例 #14
0
    def update_playlists(self, lib):
        self._log.info(u"Updating {0} smart playlists...",
                       len(self._matched_playlists))

        playlist_dir = self.config['playlist_dir'].as_filename()
        playlist_dir = bytestring_path(playlist_dir)
        relative_to = self.config['relative_to'].get()
        if relative_to:
            relative_to = normpath(relative_to)

        for playlist in self._matched_playlists:
            name, (query, q_sort), (album_query, a_q_sort) = playlist
            self._log.debug(u"Creating playlist {0}", name)
            items = []

            if query:
                items.extend(lib.items(query, q_sort))
            if album_query:
                for album in lib.albums(album_query, a_q_sort):
                    items.extend(album.items())

            m3us = {}
            # As we allow tags in the m3u names, we'll need to iterate through
            # the items and generate the correct m3u file names.
            for item in items:
                m3u_name = item.evaluate_template(name, True)
                m3u_name = sanitize_path(m3u_name, lib.replacements)
                if m3u_name not in m3us:
                    m3us[m3u_name] = []
                item_path = item.path
                if relative_to:
                    item_path = os.path.relpath(item.path, relative_to)
                if item_path not in m3us[m3u_name]:
                    m3us[m3u_name].append(item_path)
            # Now iterate through the m3us that we need to generate
            for m3u in m3us:
                m3u_path = normpath(
                    os.path.join(playlist_dir, bytestring_path(m3u)))
                mkdirall(m3u_path)
                with open(syspath(m3u_path), 'wb') as f:
                    for path in m3us[m3u]:
                        f.write(path + b'\n')

        self._log.info(u"{0} playlists updated", len(self._matched_playlists))
コード例 #15
0
ファイル: library.py プロジェクト: leagloriane/beets
    def art_destination(self, image, item_dir=None):
        """Returns a path to the destination for the album art image
        for the album. `image` is the path of the image that will be
        moved there (used for its extension).

        The path construction uses the existing path of the album's
        items, so the album must contain at least one item or
        item_dir must be provided.
        """
        image = bytestring_path(image)
        item_dir = item_dir or self.item_dir()

        filename_tmpl = Template(beets.config['art_filename'].get(unicode))
        subpath = self.evaluate_template(filename_tmpl, True)
        subpath = util.sanitize_path(subpath,
                                     replacements=self._db.replacements)
        subpath = bytestring_path(subpath)

        _, ext = os.path.splitext(image)
        dest = os.path.join(item_dir, subpath + ext)

        return bytestring_path(dest)
コード例 #16
0
    def art_destination(self, image, item_dir=None):
        """Returns a path to the destination for the album art image
        for the album. `image` is the path of the image that will be
        moved there (used for its extension).

        The path construction uses the existing path of the album's
        items, so the album must contain at least one item or
        item_dir must be provided.
        """
        image = bytestring_path(image)
        item_dir = item_dir or self.item_dir()

        filename_tmpl = Template(beets.config['art_filename'].get(unicode))
        subpath = self.evaluate_template(filename_tmpl, True)
        subpath = util.sanitize_path(subpath,
                                     replacements=self._db.replacements)
        subpath = bytestring_path(subpath)

        _, ext = os.path.splitext(image)
        dest = os.path.join(item_dir, subpath + ext)

        return bytestring_path(dest)
コード例 #17
0
 def test_sanitize_with_custom_replace_overrides_built_in_sub(self):
     with _common.platform_posix():
         p = util.sanitize_path(u'a/.?/b', [
             (re.compile(r'foo'), u'bar'),
         ])
     self.assertEqual(p, u'a/.?/b')
コード例 #18
0
 def test_sanitize_windows_replaces_trailing_space(self):
     with _common.platform_windows():
         p = util.sanitize_path(u'one/two /three')
     self.assertFalse(u' ' in p)
コード例 #19
0
 def test_sanitize_unix_replaces_leading_dot(self):
     with _common.platform_posix():
         p = util.sanitize_path(u'one/.two/three')
     self.assertFalse(u'.' in p)
コード例 #20
0
ファイル: test_db.py プロジェクト: sbuser/beets
 def test_sanitize_with_custom_replace_adds_replacements(self):
     p = util.sanitize_path("foo/bar", posixpath, [(re.compile(r"foo"), "bar")])
     self.assertEqual(p, "bar/bar")
コード例 #21
0
ファイル: test_db.py プロジェクト: coolkehon/beets
 def test_sanitize_with_custom_replace_adds_replacements(self):
     p = util.sanitize_path('foo/bar', posixpath, [
         (re.compile(r'foo'), 'bar'),
     ])
     self.assertEqual(p, 'bar/bar')
コード例 #22
0
ファイル: test_library.py プロジェクト: ykumar6/beets
 def test_sanitize_path_returns_unicode(self):
     path = u'b\xe1r?'
     new_path = util.sanitize_path(path)
     self.assert_(isinstance(new_path, unicode))
コード例 #23
0
ファイル: library.py プロジェクト: sbuser/beets
 def destination(self, item, pathmod=None, in_album=False,
                 fragment=False, basedir=None):
     """Returns the path in the library directory designated for item
     item (i.e., where the file ought to be). in_album forces the
     item to be treated as part of an album. fragment makes this
     method return just the path fragment underneath the root library
     directory; the path is also returned as Unicode instead of
     encoded as a bytestring. basedir can override the library's base
     directory for the destination.
     """
     pathmod = pathmod or os.path
     
     # Use a path format based on a query, falling back on the
     # default.
     for query, path_format in self.path_formats:
         if query == PF_KEY_DEFAULT:
             continue
         query = AndQuery.from_string(query)
         if in_album:
             # If we're treating this item as a member of the item,
             # hack the query so that singleton queries always
             # observe the item to be non-singleton.
             for i, subquery in enumerate(query):
                 if isinstance(subquery, SingletonQuery):
                     query[i] = FalseQuery() if subquery.sense \
                                else TrueQuery()
         if query.match(item):
             # The query matches the item! Use the corresponding path
             # format.
             break
     else:
         # No query matched; fall back to default.
         for query, path_format in self.path_formats:
             if query == PF_KEY_DEFAULT:
                 break
         else:
             assert False, "no default path format"
     subpath_tmpl = Template(path_format)
     
     # Get the item's Album if it has one.
     album = self.get_album(item)
     
     # Build the mapping for substitution in the path template,
     # beginning with the values from the database.
     mapping = {}
     for key in ITEM_KEYS_META:
         # Get the values from either the item or its album.
         if key in ALBUM_KEYS_ITEM and album is not None:
             # From album.
             value = getattr(album, key)
         else:
             # From Item.
             value = getattr(item, key)
         mapping[key] = util.sanitize_for_path(value, pathmod, key)
     
     # Use the album artist if the track artist is not set and
     # vice-versa.
     if not mapping['artist']:
         mapping['artist'] = mapping['albumartist']
     if not mapping['albumartist']:
         mapping['albumartist'] = mapping['artist']
     
     # Perform substitution.
     mapping.update(plugins.template_values(item))
     funcs = dict(TEMPLATE_FUNCTIONS)
     funcs.update(plugins.template_funcs())
     subpath = subpath_tmpl.substitute(mapping, funcs)
     
     # Encode for the filesystem, dropping unencodable characters.
     if isinstance(subpath, unicode) and not fragment:
         encoding = sys.getfilesystemencoding() or sys.getdefaultencoding()
         subpath = subpath.encode(encoding, 'replace')
     
     # Truncate components and remove forbidden characters.
     subpath = util.sanitize_path(subpath, pathmod, self.replacements)
     
     # Preserve extension.
     _, extension = pathmod.splitext(item.path)
     subpath += extension
     
     if fragment:
         return subpath
     else:
         basedir = basedir or self.directory
         return normpath(os.path.join(basedir, subpath))   
コード例 #24
0
ファイル: test_db.py プロジェクト: nateroling/beets
 def test_sanitize_path_returns_bytestring(self):
     path = 'b\xe1r?'
     new_path = util.sanitize_path(path)
     self.assert_(isinstance(new_path, str))
コード例 #25
0
ファイル: test_db.py プロジェクト: nateroling/beets
 def test_sanitize_with_custom_replace_adds_replacements(self):
     p = util.sanitize_path('foo/bar', posixpath, [
         (re.compile(r'foo'), 'bar'),
     ])
     self.assertEqual(p, 'bar/bar')
コード例 #26
0
ファイル: test_db.py プロジェクト: nateroling/beets
 def test_sanitize_with_custom_replace_overrides_built_in_sub(self):
     p = util.sanitize_path('a/.?/b', posixpath, [
         (re.compile(r'foo'), 'bar'),
     ])
     self.assertEqual(p, 'a/.?/b')
コード例 #27
0
ファイル: test_db.py プロジェクト: nateroling/beets
 def test_sanitize_replaces_colon_with_dash(self):
     p = util.sanitize_path(u':', posixpath)
     self.assertEqual(p, u'-')
コード例 #28
0
ファイル: test_db.py プロジェクト: nateroling/beets
 def test_sanitize_windows_replaces_trailing_dot(self):
     p = util.sanitize_path('one/two./three', ntpath)
     self.assertFalse('.' in p)
コード例 #29
0
ファイル: library.py プロジェクト: navinpai/beets
 def destination(self, item, pathmod=None, in_album=False,
                 fragment=False, basedir=None):
     """Returns the path in the library directory designated for item
     item (i.e., where the file ought to be). in_album forces the
     item to be treated as part of an album. fragment makes this
     method return just the path fragment underneath the root library
     directory; the path is also returned as Unicode instead of
     encoded as a bytestring. basedir can override the library's base
     directory for the destination.
     """
     pathmod = pathmod or os.path
     
     # Use a path format based on the album type, if available.
     if not item.album_id and not in_album:
         # Singleton track. Never use the "album" formats.
         if 'singleton' in self.path_formats:
             path_format = self.path_formats['singleton']
         else:
             path_format = self.path_formats['default']
     elif item.albumtype and item.albumtype in self.path_formats:
         path_format = self.path_formats[item.albumtype]
     elif item.comp and 'comp' in self.path_formats:
         path_format = self.path_formats['comp']
     else:
         path_format = self.path_formats['default']
     subpath_tmpl = Template(path_format)
     
     # Get the item's Album if it has one.
     album = self.get_album(item)
     
     # Build the mapping for substitution in the path template,
     # beginning with the values from the database.
     mapping = {}
     for key in ITEM_KEYS_META:
         # Get the values from either the item or its album.
         if key in ALBUM_KEYS_ITEM and album is not None:
             # From album.
             value = getattr(album, key)
         else:
             # From Item.
             value = getattr(item, key)
         mapping[key] = util.sanitize_for_path(value, pathmod, key)
     
     # Use the album artist if the track artist is not set and
     # vice-versa.
     if not mapping['artist']:
         mapping['artist'] = mapping['albumartist']
     if not mapping['albumartist']:
         mapping['albumartist'] = mapping['artist']
     
     # Perform substitution.
     subpath = subpath_tmpl.substitute(mapping)
     
     # Encode for the filesystem, dropping unencodable characters.
     if isinstance(subpath, unicode) and not fragment:
         encoding = sys.getfilesystemencoding() or sys.getdefaultencoding()
         subpath = subpath.encode(encoding, 'replace')
     
     # Truncate components and remove forbidden characters.
     subpath = util.sanitize_path(subpath)
     
     # Preserve extension.
     _, extension = pathmod.splitext(item.path)
     subpath += extension
     
     if fragment:
         return subpath
     else:
         basedir = basedir or self.directory
         return normpath(os.path.join(basedir, subpath))   
コード例 #30
0
ファイル: test_db.py プロジェクト: coolkehon/beets
 def test_sanitize_path_returns_bytestring(self):
     path = 'b\xe1r?'
     new_path = util.sanitize_path(path)
     self.assert_(isinstance(new_path, str))
コード例 #31
0
 def test_sanitize_empty_component(self):
     with _common.platform_posix():
         p = util.sanitize_path(u'foo//bar', [
             (re.compile(r'^$'), u'_'),
         ])
     self.assertEqual(p, u'foo/_/bar')
コード例 #32
0
ファイル: test_library.py プロジェクト: pprkut/beets
 def test_sanitize_path_returns_unicode(self):
     path = u'b\xe1r?'
     new_path = util.sanitize_path(path)
     self.assertTrue(isinstance(new_path, six.text_type))
コード例 #33
0
ファイル: test_library.py プロジェクト: zedwarth/beets
 def test_sanitize_path_returns_unicode(self):
     path = u'b\xe1r?'
     new_path = util.sanitize_path(path)
     self.assertTrue(isinstance(new_path, six.text_type))
コード例 #34
0
ファイル: test_db.py プロジェクト: jenzie/beets
 def test_sanitize_path_works_on_empty_string(self):
     p = util.sanitize_path(u'', posixpath)
     self.assertEqual(p, u'')
コード例 #35
0
ファイル: test_util.py プロジェクト: JDLH/beets
 def test_sanitize_empty_component(self):
     with _common.platform_posix():
         p = util.sanitize_path(u'foo//bar', [
             (re.compile(r'^$'), u'_'),
         ])
     self.assertEqual(p, u'foo/_/bar')
コード例 #36
0
ファイル: library.py プロジェクト: leagloriane/beets
    def destination(self, fragment=False, basedir=None, platform=None,
                    path_formats=None):
        """Returns the path in the library directory designated for the
        item (i.e., where the file ought to be). fragment makes this
        method return just the path fragment underneath the root library
        directory; the path is also returned as Unicode instead of
        encoded as a bytestring. basedir can override the library's base
        directory for the destination.
        """
        self._check_db()
        platform = platform or sys.platform
        basedir = basedir or self._db.directory
        path_formats = path_formats or self._db.path_formats

        # Use a path format based on a query, falling back on the
        # default.
        for query, path_format in path_formats:
            if query == PF_KEY_DEFAULT:
                continue
            query = get_query(query, type(self))
            if query.match(self):
                # The query matches the item! Use the corresponding path
                # format.
                break
        else:
            # No query matched; fall back to default.
            for query, path_format in path_formats:
                if query == PF_KEY_DEFAULT:
                    break
            else:
                assert False, "no default path format"
        if isinstance(path_format, Template):
            subpath_tmpl = path_format
        else:
            subpath_tmpl = Template(path_format)

        # Evaluate the selected template.
        subpath = self.evaluate_template(subpath_tmpl, True)

        # Prepare path for output: normalize Unicode characters.
        if platform == 'darwin':
            subpath = unicodedata.normalize('NFD', subpath)
        else:
            subpath = unicodedata.normalize('NFC', subpath)
        # Truncate components and remove forbidden characters.
        subpath = util.sanitize_path(subpath, self._db.replacements)
        # Encode for the filesystem.
        if not fragment:
            subpath = bytestring_path(subpath)

        # Preserve extension.
        _, extension = os.path.splitext(self.path)
        if fragment:
            # Outputting Unicode.
            extension = extension.decode('utf8', 'ignore')
        subpath += extension.lower()

        # Truncate too-long components.
        maxlen = beets.config['max_filename_length'].get(int)
        if not maxlen:
            # When zero, try to determine from filesystem.
            maxlen = util.max_filename_length(self._db.directory)
        subpath = util.truncate_path(subpath, maxlen)

        if fragment:
            return subpath
        else:
            return normpath(os.path.join(basedir, subpath))
コード例 #37
0
ファイル: test_db.py プロジェクト: Bitdemon/beets
 def test_sanitize_unix_replaces_leading_dot(self):
     p = util.sanitize_path(u'one/.two/three', posixpath)
     self.assertFalse('.' in p)
コード例 #38
0
ファイル: test_library.py プロジェクト: Brainversation/beets
 def test_sanitize_path_returns_unicode(self):
     path = u'b\xe1r?'
     new_path = util.sanitize_path(path)
     self.assert_(isinstance(new_path, unicode))
コード例 #39
0
ファイル: test_db.py プロジェクト: coolkehon/beets
 def test_sanitize_replaces_colon_with_dash(self):
     p = util.sanitize_path(u':', posixpath)
     self.assertEqual(p, u'-')
コード例 #40
0
def rename_files(host_filter, torrent_filter, btn_api_key, orpheus_api_key,
                 redacted_api_key):
    hosts = DELUGE_API()
    apis = []

    if (btn_api_key):
        logger.trace('Testing BTN API configuration')
        btn_api = BTN_API(btn_api_key)
        btn_index = btn_api.get_index()
        logger.success(f'Connected to BTN as {btn_index.username}')
        apis.append(btn_api)

    if (orpheus_api_key):
        logger.trace('Testing Orpheus API configuration')
        orp_api = ORP_API(orpheus_api_key)
        orp_index = orp_api.get_index()
        logger.success(f'Connected to Orpheus as {orp_index.username}')
        apis.append(orp_api)

    if (redacted_api_key):
        logger.trace('Testing Redacted API configuration')
        red_api = RED_API(redacted_api_key)
        red_index = red_api.get_index()
        logger.success(f'Connected to Redacted as {red_index.username}')
        apis.append(red_api)

    host_filter = compile(host_filter) if not isinstance(
        host_filter, Pattern) else host_filter
    torrent_filter = compile(torrent_filter) if not isinstance(
        torrent_filter, Pattern) else torrent_filter

    filtered_hosts = [host for host in hosts if host_filter.search(str(host))]
    logger.info(f'{hosts} ({len(filtered_hosts)} filtered):')
    total_torrents = 0
    total_files = 0
    renamed_torrents = 0
    renamed_files = 0
    failed_torrents = 0
    failed_files = 0
    for host in filtered_hosts:
        logger.info(f'  {host}:')
        filtered_torrents = [
            torrent for torrent in host.torrents
            if torrent_filter.search(str(torrent))
        ]
        logger.info(
            f'    {host.torrents} ({len(filtered_torrents)} filtered):')
        for torrent in filtered_torrents:
            total_torrents += 1
            logger.info(f'      {torrent}:')
            logger.info(f'        {torrent.trackers}:')
            for tracker in torrent.trackers:
                logger.info(f'          {tracker}')
            logger.info(f'        {torrent.files}:')
            changed = False
            failed = False
            prompt = False
            for api in apis:
                if torrent.trackers.tracker in api.supported_trackers:
                    logger.success(f'Renaming files with {type(api)}')
                    for file in torrent.files:
                        total_files += 1
                        logger.info(f'          {file}')
                        result = api.rename_torrent_file(
                            torrent.hash, file.path)
                        if result is None:
                            failed_files += 1
                            failed = True
                            continue
                        path = sanitize_path(
                            asciify_path(unescape(result), '_')).replace(
                                '_', '').replace(' (VBR)]', ']')
                        if file.path != path and (not prompt or confirm(
                                f'Rename {file.path} to {path}?',
                                default=True)):
                            renamed_files += 1
                            file.path = path
                            changed = True
            if changed:
                renamed_torrents += 1
                torrent.force_recheck()
            if failed:
                failed_torrents += 1

    echo(f'Checked {total_files} files in {total_torrents} torrents', nl=False)
    if renamed_files > 0:
        echo(', ' + style(
            f'renamed {renamed_files} files in {renamed_torrents} torrents',
            fg='green'),
             nl=False)
    if failed_files > 0:
        echo(
            ', ' +
            style(f'failed {failed_files} files in {failed_torrents} torrents',
                  fg='red'),
            nl=False)
    echo('.')
コード例 #41
0
ファイル: test_db.py プロジェクト: Bitdemon/beets
 def test_sanitize_windows_replaces_trailing_space(self):
     p = util.sanitize_path(u'one/two /three', ntpath)
     self.assertFalse(' ' in p)
コード例 #42
0
ファイル: test_db.py プロジェクト: sbuser/beets
 def test_sanitize_with_custom_replace_overrides_built_in_sub(self):
     p = util.sanitize_path("a/.?/b", posixpath, [(re.compile(r"foo"), "bar")])
     self.assertEqual(p, "a/.?/b")
コード例 #43
0
ファイル: test_db.py プロジェクト: coolkehon/beets
 def test_sanitize_windows_replaces_trailing_dot(self):
     p = util.sanitize_path('one/two./three', ntpath)
     self.assertFalse('.' in p)
コード例 #44
0
 def test_sanitize_path_works_on_empty_string(self):
     with _common.platform_posix():
         p = util.sanitize_path(u'')
     self.assertEqual(p, u'')
コード例 #45
0
    def destination(self, fragment=False, basedir=None, platform=None,
                    path_formats=None):
        """Returns the path in the library directory designated for the
        item (i.e., where the file ought to be). fragment makes this
        method return just the path fragment underneath the root library
        directory; the path is also returned as Unicode instead of
        encoded as a bytestring. basedir can override the library's base
        directory for the destination.
        """
        self._check_db()
        platform = platform or sys.platform
        basedir = basedir or self._db.directory
        path_formats = path_formats or self._db.path_formats

        # Use a path format based on a query, falling back on the
        # default.
        for query, path_format in path_formats:
            if query == PF_KEY_DEFAULT:
                continue
            query = get_query(query, type(self))
            if query.match(self):
                # The query matches the item! Use the corresponding path
                # format.
                break
        else:
            # No query matched; fall back to default.
            for query, path_format in path_formats:
                if query == PF_KEY_DEFAULT:
                    break
            else:
                assert False, "no default path format"
        if isinstance(path_format, Template):
            subpath_tmpl = path_format
        else:
            subpath_tmpl = Template(path_format)

        # Evaluate the selected template.
        subpath = self.evaluate_template(subpath_tmpl, True)

        # Prepare path for output: normalize Unicode characters.
        if platform == 'darwin':
            subpath = unicodedata.normalize('NFD', subpath)
        else:
            subpath = unicodedata.normalize('NFC', subpath)
        # Truncate components and remove forbidden characters.
        subpath = util.sanitize_path(subpath, self._db.replacements)
        # Encode for the filesystem.
        if not fragment:
            subpath = bytestring_path(subpath)

        # Preserve extension.
        _, extension = os.path.splitext(self.path)
        if fragment:
            # Outputting Unicode.
            extension = extension.decode('utf8', 'ignore')
        subpath += extension.lower()

        # Truncate too-long components.
        maxlen = beets.config['max_filename_length'].get(int)
        if not maxlen:
            # When zero, try to determine from filesystem.
            maxlen = util.max_filename_length(self._db.directory)
        subpath = util.truncate_path(subpath, maxlen)

        if fragment:
            return subpath
        else:
            return normpath(os.path.join(basedir, subpath))
コード例 #46
0
 def test_sanitize_with_custom_replace_adds_replacements(self):
     with _common.platform_posix():
         p = util.sanitize_path(u'foo/bar', [
             (re.compile(r'foo'), u'bar'),
         ])
     self.assertEqual(p, u'bar/bar')
コード例 #47
0
ファイル: test_library.py プロジェクト: Brainversation/beets
 def test_sanitize_unix_replaces_leading_dot(self):
     with _common.platform_posix():
         p = util.sanitize_path(u'one/.two/three')
     self.assertFalse('.' in p)
コード例 #48
0
ファイル: test_library.py プロジェクト: pprkut/beets
 def test_sanitize_path_with_special_chars(self):
     path = u'b\xe1r?'
     new_path = util.sanitize_path(path)
     self.assertTrue(new_path.startswith(u'b\xe1r'))
コード例 #49
0
ファイル: test_db.py プロジェクト: sbuser/beets
 def test_sanitize_path_with_special_chars(self):
     path = "b\xe1r?"
     new_path = util.sanitize_path(path)
     self.assert_(new_path.startswith("b\xe1r"))
コード例 #50
0
ファイル: test_db.py プロジェクト: jenzie/beets
 def test_sanitize_unix_replaces_leading_dot(self):
     p = util.sanitize_path(u'one/.two/three', posixpath)
     self.assertFalse('.' in p)
コード例 #51
0
ファイル: test_library.py プロジェクト: Brainversation/beets
 def test_sanitize_windows_replaces_trailing_space(self):
     with _common.platform_windows():
         p = util.sanitize_path(u'one/two /three')
     self.assertFalse(' ' in p)
コード例 #52
0
ファイル: test_db.py プロジェクト: jenzie/beets
 def test_sanitize_windows_replaces_trailing_space(self):
     p = util.sanitize_path(u'one/two /three', ntpath)
     self.assertFalse(' ' in p)
コード例 #53
0
ファイル: test_library.py プロジェクト: Brainversation/beets
 def test_sanitize_path_works_on_empty_string(self):
     with _common.platform_posix():
         p = util.sanitize_path(u'')
     self.assertEqual(p, u'')
コード例 #54
0
ファイル: test_library.py プロジェクト: ykumar6/beets
 def test_sanitize_path_with_special_chars(self):
     path = u'b\xe1r?'
     new_path = util.sanitize_path(path)
     self.assert_(new_path.startswith(u'b\xe1r'))
コード例 #55
0
ファイル: test_library.py プロジェクト: Brainversation/beets
 def test_sanitize_with_custom_replace_overrides_built_in_sub(self):
     with _common.platform_posix():
         p = util.sanitize_path(u'a/.?/b', [
             (re.compile(ur'foo'), u'bar'),
         ])
     self.assertEqual(p, u'a/.?/b')
コード例 #56
0
 def destination(self, item, pathmod=None, in_album=False,
                 fragment=False, basedir=None):
     """Returns the path in the library directory designated for item
     item (i.e., where the file ought to be). in_album forces the
     item to be treated as part of an album. fragment makes this
     method return just the path fragment underneath the root library
     directory; the path is also returned as Unicode instead of
     encoded as a bytestring. basedir can override the library's base
     directory for the destination.
     """
     pathmod = pathmod or os.path
     
     # Use a path format based on a query, falling back on the
     # default.
     for query, path_format in self.path_formats:
         if query == PF_KEY_DEFAULT:
             continue
         query = AndQuery.from_string(query)
         if in_album:
             # If we're treating this item as a member of the item,
             # hack the query so that singleton queries always
             # observe the item to be non-singleton.
             for i, subquery in enumerate(query):
                 if isinstance(subquery, SingletonQuery):
                     query[i] = FalseQuery() if subquery.sense \
                                else TrueQuery()
         if query.match(item):
             # The query matches the item! Use the corresponding path
             # format.
             break
     else:
         # No query matched; fall back to default.
         for query, path_format in self.path_formats:
             if query == PF_KEY_DEFAULT:
                 break
         else:
             assert False, "no default path format"
     subpath_tmpl = Template(path_format)
     
     # Get the item's Album if it has one.
     album = self.get_album(item)
     
     # Build the mapping for substitution in the path template,
     # beginning with the values from the database.
     mapping = {}
     for key in ITEM_KEYS_META:
         # Get the values from either the item or its album.
         if key in ALBUM_KEYS_ITEM and album is not None:
             # From album.
             value = getattr(album, key)
         else:
             # From Item.
             value = getattr(item, key)
         mapping[key] = util.sanitize_for_path(value, pathmod, key)
     
     # Use the album artist if the track artist is not set and
     # vice-versa.
     if not mapping['artist']:
         mapping['artist'] = mapping['albumartist']
     if not mapping['albumartist']:
         mapping['albumartist'] = mapping['artist']
     
     # Perform substitution.
     mapping.update(plugins.template_values(item))
     funcs = dict(TEMPLATE_FUNCTIONS)
     funcs.update(plugins.template_funcs())
     subpath = subpath_tmpl.substitute(mapping, funcs)
     
     # Encode for the filesystem, dropping unencodable characters.
     if isinstance(subpath, unicode) and not fragment:
         encoding = sys.getfilesystemencoding() or sys.getdefaultencoding()
         subpath = subpath.encode(encoding, 'replace')
     
     # Truncate components and remove forbidden characters.
     subpath = util.sanitize_path(subpath, pathmod, self.replacements)
     
     # Preserve extension.
     _, extension = pathmod.splitext(item.path)
     subpath += extension
     
     if fragment:
         return subpath
     else:
         basedir = basedir or self.directory
         return normpath(os.path.join(basedir, subpath))   
コード例 #57
0
ファイル: test_library.py プロジェクト: Brainversation/beets
 def test_sanitize_with_custom_replace_adds_replacements(self):
     with _common.platform_posix():
         p = util.sanitize_path(u'foo/bar', [
             (re.compile(ur'foo'), u'bar'),
         ])
     self.assertEqual(p, u'bar/bar')
コード例 #58
0
ファイル: test_db.py プロジェクト: Bitdemon/beets
 def test_sanitize_path_works_on_empty_string(self):
     p = util.sanitize_path(u'', posixpath)
     self.assertEqual(p, u'')
コード例 #59
0
ファイル: test_db.py プロジェクト: coolkehon/beets
 def test_sanitize_with_custom_replace_overrides_built_in_sub(self):
     p = util.sanitize_path('a/.?/b', posixpath, [
         (re.compile(r'foo'), 'bar'),
     ])
     self.assertEqual(p, 'a/.?/b')