def cover_path(self): mbid = self.song.get('musicbrainz_albumid', None) # It is beneficial to use mbid for cover names. if mbid: return path.join(cover_dir, escape_filename(mbid)) else: return super(LastFMCover, self).cover_path
def _downloaded(self, msg: Soup.Message, result: Any, data: Tuple) -> None: path, song = data try: headers = msg.get_property('response-headers') size = int(headers.get('content-length')) content_type = headers.get('content-type') print_d( f"Downloaded {format_size(size)} of {content_type}: {song('title')}" ) _, ext = splitext(urlparse(song("~uri")).path) fn = (escape_filename(song("~artist~title")[:100], safe=b" ,';") or song("~basename") or f"download-{hash(song('~filename'))}") path = path / Path(fn + ext) if path.is_file() and path.stat(): print_w(f"{path!s} already exists. Skipping download") self.success(song) return with open(path, "wb") as f: f.write(result) self.success(song) print_d(f"Downloaded to {path} successfully!") except Exception as e: print_e(f"Failed download ({e})") self.failure(song)
def lyric_filename(self): """Returns the (potential) lyrics filename for this file""" filename = self.comma("title").replace(u"/", u"")[:128] + u".lyric" sub_dir = (self.comma("lyricist") or self.comma("artist")).replace(u"/", u"")[:128] if os.name == "nt": # this was added at a later point. only use escape_filename here # to keep the linux case the same as before filename = escape_filename(filename) sub_dir = escape_filename(sub_dir) else: filename = fsnative(filename) sub_dir = fsnative(sub_dir) path = os.path.join(expanduser(fsnative(u"~/.lyrics")), sub_dir, filename) return path
def lyric_filename(self): """Returns the (potential) lyrics filename for this file""" filename = self.comma("title").replace(u'/', u'')[:128] + u'.lyric' sub_dir = ((self.comma("lyricist") or self.comma("artist")).replace(u'/', u'')[:128]) if os.name == "nt": # this was added at a later point. only use escape_filename here # to keep the linux case the same as before filename = escape_filename(filename) sub_dir = escape_filename(sub_dir) else: filename = fsnative(filename) sub_dir = fsnative(sub_dir) path = os.path.join(expanduser(fsnative(u"~/.lyrics")), sub_dir, filename) return path
def cover_filename(self): """ Return the filename of the cover which hopefully should not change between songs in the same album and still be unique enough to uniquely identify most (or even better – all) of the albums. The string returned must not contain any characters illegal in most common filesystems. These include /, ?, <, >, \, :, *, |, ” and ^. Staying in the bounds of ASCII is highly encouraged. Perchance the song lacks data to generate the filename of cover for this provider, None shall be returned. """ key = sha1() # Should be fine as long as the same interpreter is used. key.update(repr(self.song.album_key)) return escape_filename(key.hexdigest())
def test_lyric_filename_search_special_characters_across_path(self): """test '<' and/or '>' in name across path separator (not parsed (transparent to test))""" with self.lyric_filename_test_setup(no_config=True) as ts: # test '<' and '>' in name across path # (not parsed (transparent to test)) ts['artist'] = "a < b" ts['title'] = "b > a" parts = [ts.root, ts["artist"], ts["title"] + ".lyric"] rpf = RootPathFile(ts.root, os.path.sep.join(parts)) rootp = ts.root rmdirs = [] # ensure valid dir existence for p in rpf.end.split(os.path.sep)[:-1]: rootp = os.path.sep.join([ts.root, p]) if not RootPathFile(ts.root, rootp).valid: rootp = os.path.sep.join([ts.root, escape_filename(p)]) self.assertTrue( RootPathFile(ts.root, rootp).valid, "even escaped target dir part is not valid!") if not os.path.exists(rootp): mkdir(rootp) rmdirs.append(rootp) if not rpf.valid: rpf = RootPathFile(rpf.root, rpf.pathfile_escaped) with io.open(rpf.pathfile, "w", encoding='utf-8') as f: f.write(u"") # search for lyric file search = ts.lyric_filename # clean up test lyric file / path os.remove(rpf.pathfile) for p in rmdirs: os.rmdir(p) # test whether the 'found' file is the test lyric file fp = rpf.pathfile if is_windows(): fp = fp.lower() # account for 'os.path.normcase' santisatation search = search.lower() # compensate for the above self.assertEqual(search, fp)
def test_lyric_filename_search_special_characters_across_path(self): """test '<' and/or '>' in name across path separator (not parsed (transparent to test))""" with self.lyric_filename_test_setup(no_config=True) as ts: # test '<' and '>' in name across path # (not parsed (transparent to test)) ts['artist'] = "a < b" ts['title'] = "b > a" parts = [ts.root, ts["artist"], ts["title"] + ".lyric"] rpf = RootPathFile(ts.root, os.path.sep.join(parts)) rootp = ts.root rmdirs = [] # ensure valid dir existence for p in rpf.end.split(os.path.sep)[:-1]: rootp = os.path.sep.join([ts.root, p]) if not RootPathFile(ts.root, rootp).valid: rootp = os.path.sep.join([ts.root, escape_filename(p)]) self.assertTrue(RootPathFile(ts.root, rootp).valid, "even escaped target dir part is not valid!") if not os.path.exists(rootp): mkdir(rootp) rmdirs.append(rootp) if not rpf.valid: rpf = RootPathFile(rpf.root, rpf.pathfile_escaped) with io.open(rpf.pathfile, "w", encoding='utf-8') as f: f.write(u"") # search for lyric file search = ts.lyric_filename # clean up test lyric file / path os.remove(rpf.pathfile) for p in rmdirs: os.rmdir(p) # test whether the 'found' file is the test lyric file fp = rpf.pathfile if is_windows(): fp = fp.lower() # account for 'os.path.normcase' santisatation search = search.lower() # compensate for the above self.assertEqual(search, fp)
def cover_path(self): url = self.url if url: return path.join(cover_dir, escape_filename(url))
def test_unicode(self): result = escape_filename(u'abc\xe4') self.assertEqual(result, "abc%C3%A4") self.assertTrue(isinstance(result, fsnative))
def test_str(self): result = escape_filename("\x00\x01") self.assertEqual(result, "%00%01") self.assertTrue(isinstance(result, fsnative))
def test_safe_chars(self): result = escape_filename('1, 2, and -3', safe=' -') self.assertEqual(result, "1%2C 2%2C and -3") self.assertTrue(isinstance(result, fsnative))
def filename_for(cls, filename: str): return escape_filename(filename)
def __init__(self, backend_id, device_id): super(StorageDevice, self).__init__(backend_id, device_id) filename = escape_filename(device_id) self.__library_path = os.path.join(CACHE, filename) self.__library_name = device_id
def cover_path(self): url = self.url if url: return path.join(cover_dir, escape_filename(url)) return super(ArtworkUrlCover, self).cover_path
def cover_path(self): mbid = self.mbid if mbid is None: return super(MusicBrainzCover, self).cover_path return path.join(cover_dir, escape_filename(mbid))
def cover_path(self): mbid = self.song.get('musicbrainz_albumid', None) if mbid: return path.join(cover_dir, escape_filename(mbid)) else: return super(DiscogsCover, self).cover_path
def cover_path(self): mbid = self.song.get('musicbrainz_albumid', None) if mbid: return path.join(cover_dir, escape_filename(mbid)) else: return super().cover_path