def test_playlist_extensive(): pl = Playlist.parse("playlist-extensive.xspf") assert pl.title == "My playlist" assert pl.creator == "Jane Doe" assert pl.annotation == "My favorite songs" assert pl.info == "http://example.com/myplaylists" assert pl.location == "http://example.com/myplaylists/myplaylist" assert pl.identifier == \ "magnet:?xt=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C" assert pl.image == "http://example.com/img/mypicture" assert pl.date == datetime(2005, 1, 8, 17, 10, 47, tzinfo=timezone(timedelta(hours=-5))) assert pl.license == "http://creativecommons.org/licenses/by/1.0/" assert len(pl.attribution) == 2 assert pl.attribution[0].identifier == "http://bar.com/secondderived.xspf" assert pl.attribution[1].location == "http://foo.com/original.xspf" assert pl.link[0].rel == "http://foaf.example.org/namespace/version1" assert pl.link[0].content == \ "http://socialnetwork.example.org/foaf/mary.rdfs" assert len(pl.link) == 1 assert pl.meta[0].rel == "http://example.org/key" assert pl.meta[0].content == "value" assert len(pl.meta) == 1 # TODO: Add extension assertion assert len(pl.extension) == 1 assert pl.extension[0].application == "http://example.com" assert len(pl.trackList) == 0
def test_track_whitespace_anyURI(): tr = Playlist.parse("track-whitespace-anyURI.xspf")[0] assert len(tr.location) == 4 assert tr.location[0] == "http://example.com/no_whitespace/" assert tr.location[1] == "http://example.com/whitespace_before/" assert tr.location[2] == "http://example.com/whitespace_after/" assert tr.location[3] == "http://example.com/whitespace_before_and_after/"
def test_playlist_inverted_order(): pl = Playlist.parse("playlist-inverted-order.xspf") assert pl.title == "some text" assert pl.creator == "some text" assert pl.annotation == "some text" assert pl.info == "http://example.com/" assert pl.location == "http://example.com/" assert pl.identifier == "http://example.com/" assert pl.image == "http://example.com/" assert pl.date == datetime(2005, 1, 8, 17, 10, 47, tzinfo=timezone(timedelta(hours=-5))) assert pl.license == "http://example.com/" # TODO: check attribution assert pl.link[0].rel == "http://example.com/" assert pl.link[0].content == "http://example.com/" assert len(pl.link) == 2 assert pl.meta[0].rel == "http://example.com/" assert pl.meta[0].content == "value" assert len(pl.meta) == 2 assert pl.extension[0].application == 'http://example.com/' assert len(pl.extension) == 2 assert len(pl.trackList) == 0
def test_playlist_init(): pl = Playlist( title="That playlist", creator="myself", annotation="additional user info", info="https://path_to_more.info", location="file:///playlist.xspf", identifier="this.playlist", image="file:///default_cover.png", license="CC", attribution=[ Playlist(identifier="previous.playlist", location="file:///last.playlist.xspf") ], link=[Link("link_type", "link_uri")], meta=[ Meta("meta_type1", "metadata1"), Meta("meta_type1", "metadata2") ], extension=[Extension("appl", content=[Element('a', {'attr': "1"})])], trackList=[Track(title="tr1"), Track(title="tr2")]) pl.date = datetime(2020, 4, 20, 12, 30, 1, 123456) response = '<playlist version="1" xmlns="http://xspf.org/ns/0/">'\ '<title>That playlist</title>'\ '<creator>myself</creator>'\ '<annotation>additional user info</annotation>'\ '<info>https://path_to_more.info</info>'\ '<location>file:///playlist.xspf</location>'\ '<identifier>this.playlist</identifier>'\ '<image>file:///default_cover.png</image>'\ '<date>2020-04-20T12:30:01.123456</date>'\ '<license>CC</license>'\ '<attribution>'\ '<location>file:///last.playlist.xspf</location>'\ '<identifier>previous.playlist</identifier>'\ '</attribution>'\ '<link rel="link_type">link_uri</link>'\ '<meta rel="meta_type1">metadata1</meta>'\ '<meta rel="meta_type1">metadata2</meta>'\ '<extension application="appl">''<a attr="1" /></extension>'\ '<trackList>'\ '<track><title>tr1</title></track>'\ '<track><title>tr2</title></track>'\ '</trackList>'\ '</playlist>' assert pl.xml_string() == response
def test_playlist_relative_paths(): pl = Playlist.parse("playlist-relative-paths.xspf") assert pl[0].location[0] == "../01-Ain't Mine.flac" assert pl[0].title == "Ain't Mine" assert pl[1].location[0] == "02-Solitude over the River.flac" assert pl[1].title == "Solitude over the River" assert pl[2].location[0] == "./03-Jack Man.flac" assert pl[2].title == "Jack Man"
def test_playlist_writing(): import xspf_lib as xspf killer_queen = Track(location="file:///home/music/killer_queen.mp3", title="Killer Queen", creator="Queen", album="Sheer Heart Attack", trackNum=2, duration=177000, annotation="#2 in GB 1975", info="https://ru.wikipedia.org/wiki/Killer_Queen", image="file:///home/images/killer_queen_cover.png") anbtd = Track() anbtd.location = [ "https://freemusic.example.com/loc.ogg", "file:///home/music/anbtd.mp3" ] anbtd.title = "Another One Bites the Dust" anbtd.creator = "Queen" anbtd.identifier = ["id1.group"] anbtd.link = [Link("link.namespace", "link.uri.info")] anbtd.meta = [Meta("meta.namespace", "METADATA_INFO")] playlist = Playlist(title="Some Tracks", creator="myself", annotation="I did this only for examples!.", trackList=[killer_queen, anbtd]) playlist.date = datetime(2020, 4, 20, 12, 30, 1, 123456) playlist.write("some_tracks.xspf") with open('some_tracks.xspf', 'r') as file: playlist_xml = file.read() assert playlist_xml == '<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n'\ '<playlist version="1" xmlns="http://xspf.org/ns/0/"><title>Some'\ ' Tracks</title><creator>myself</creator><annotation>I did this '\ 'only for examples!.</annotation><date>2020-04-20T12:30:01.123456'\ '</date><trackList><track><location>'\ 'file:///home/music/killer_queen.mp3</location><title>Killer Queen'\ '</title><creator>Queen</creator><annotation>#2 in GB 1975'\ '</annotation><info>https://ru.wikipedia.org/wiki/Killer_Queen'\ '</info><image>file:///home/images/killer_queen_cover.png</image>'\ '<album>Sheer Heart Attack</album><trackNum>2</trackNum><duration>'\ '177000</duration></track><track><location>'\ 'https://freemusic.example.com/loc.ogg</location><location>'\ 'file:///home/music/anbtd.mp3</location><identifier>id1.group'\ '</identifier><title>Another One Bites the Dust</title><creator>'\ 'Queen</creator><link rel="link.namespace">link.uri.info</link>'\ '<meta rel="meta.namespace">METADATA_INFO</meta></track></trackList>'\ '</playlist>' os.remove('some_tracks.xspf')
def test_playlist_whitespace_dateTime(): pl = Playlist.parse("playlist-whitespace-dateTime.xspf") assert pl.date == datetime(2005, 1, 8, 17, 10, 47, tzinfo=timezone(timedelta(hours=-5)))
def update_metadata(ctx): """Updates the meta data of the tracks based on tags of the files.""" playlist_path = ctx.obj.playlist util.ensure_playlist_exists(playlist_path) playlist = Playlist.parse(playlist_path) playlist.trackList = list(map(util.update_metadata, playlist.trackList)) util.save_playlist(playlist, playlist_path)
def show(ctx): """Displays the playlist.""" playlist_path = ctx.obj.playlist util.ensure_playlist_exists(playlist_path) playlist = Playlist.parse(playlist_path) for idx, track in enumerate(playlist.trackList): print("[{}]\t{} - {}".format(idx + 1, track.creator, track.title))
def create(ctx, title, creator, annotation): """Creates a new playlist.""" playlist_path = ctx.obj.playlist if os.path.isfile(playlist_path): print("playlist \"{}\" already exists".format(playlist_path)) sys.exit(1) playlist = Playlist(title=title, creator=creator, annotation=annotation) util.save_playlist(playlist, playlist_path)
def remove(ctx, track_number): """Removes a track from a playlist.""" playlist_path = ctx.obj.playlist util.ensure_playlist_exists(playlist_path) playlist = Playlist.parse(playlist_path) if len(playlist.trackList) >= track_number - 1: del playlist.trackList[track_number - 1] else: sys.exit(1) util.save_playlist(playlist, playlist_path)
def add(ctx, track): """add a track to a playlist.""" playlist_path = ctx.obj.playlist util.ensure_playlist_exists(playlist_path) playlist = Playlist.parse(playlist_path) track = util.get_track_from_file(track) if track is None: print("can't add track: invalid file") sys.exit(1) playlist.trackList.append(track) util.save_playlist(playlist, playlist_path)
def test_track_inverted_order(): tr = Playlist.parse("track-inverted-order.xspf")[0] assert len(tr.location) == 1 assert tr.location[0] == "http://example.com/" assert len(tr.identifier) == 1 assert tr.identifier[0] == "http://example.com/" assert tr.title == "some text" assert tr.creator == "some text" assert tr.annotation == "some text" assert tr.info == "http://example.com/" assert tr.image == "http://example.com/" assert tr.trackNum == 2 assert tr.duration == 120000 assert len(tr.link) == 2 assert all(link.rel == "http://example.com/" for link in tr.link) assert all(link.content == "http://example.com/" for link in tr.link) assert len(tr.meta) == 2 assert all(meta.rel == "http://example.com/" for meta in tr.meta) assert all(meta.content == "value" for meta in tr.meta) assert len(tr.extension) == 2 assert all(extension.application == "http://example.com/" for extension in tr.extension)
def test_track_extensive(): tr = Playlist.parse("track-extensive.xspf")[0] assert len(tr.location) == 1 assert tr.location[0] == "http://example.com/my.mp3" assert len(tr.identifier) == 1 assert tr.identifier[0] == \ "magnet:?xt=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C" assert tr.title == "My Way" assert tr.creator == "Frank Sinatra" assert tr.annotation == "This is my theme song." assert tr.info == "http://franksinatra.com/myway" assert tr.image == "http://franksinatra.com/img/myway" assert tr.album == "Frank Sinatra's Greatest Hits" assert tr.trackNum == 3 assert tr.duration == 19200 assert len(tr.link) == 1 assert tr.link[0].rel == "http://foaf.org/namespace/version1" assert tr.link[0].content == "http://socialnetwork.org/foaf/mary.rdfs" assert len(tr.meta) == 1 assert tr.meta[0].rel == "http://example.org/key" assert tr.meta[0].content == "value" assert len(tr.extension) == 1 assert tr.extension[0].application == "http://example.com"
def test_playlist_markup_creator(): with pytest.raises(ValueError): Playlist.parse(get_testfile("playlist-markup-creator.xspf"))
def test_track_noturi_meta_rel(): with pytest.raises(ValueError): Playlist.parse(get_testfile("track-noturi-meta-rel.xspf"))
def test_track_toomany_creator(): with pytest.raises(TypeError): Playlist.parse(get_testfile("track-toomany-creator.xspf"))
def test_track_toomany_duration(): with pytest.raises(TypeError): Playlist.parse(get_testfile("track-toomany-duration.xspf"))
def test_playlist_element_forbidden_attributution(): with pytest.raises(TypeError): Playlist.parse( get_testfile("playlist-element-forbidden-attribution.xspf"))
def test_playlist_missing_version(): with pytest.raises(TypeError): Playlist.parse(get_testfile("playlist-missingversion.xspf"))
def test_also_playlist_create_empty_tracklist_element(): assert "<trackList />" in Playlist().xml_string()
def test_playlist_missing_tracklist(): with pytest.raises(TypeError): Playlist.parse(get_testfile("playlist-missingtracklist.xspf"))
def test_also_playlist_creation_without_meta_rel(): with pytest.raises(TypeError): Playlist(meta=[Meta(content="imma content")])
def test_playlist_meta_rel_missing(): with pytest.raises(TypeError): Playlist.parse(get_testfile("playlist-meta-rel-missing.xspf"))
def test_track_toomany_tracknum(): with pytest.raises(TypeError): Playlist.parse(get_testfile("track-toomany-tracknum.xspf"))
def test_track_whitespace_in_between(): with pytest.raises(ValueError): Playlist.parse(get_testfile('track-whitespace-in-between.xspf'))
def test_also_playlist_creation_without_link_rel(): with pytest.raises(TypeError): Playlist(link=Link(content="file:/let_me_in"))
def test_playlist_extension_application_missing(): with pytest.raises(TypeError): Playlist.parse( get_testfile("playlist-extension-application-missing.xspf"))
def test_playlist_markup_annotation(): with pytest.raises(ValueError): Playlist.parse(get_testfile("playlist-markup-annotation.xspf"))
def test_playlist_markup_title(): with pytest.raises(ValueError): Playlist.parse(get_testfile("playlist-markup-title.xspf"))