MCPcopy Create free account
hub / github.com/beetbox/beets / M3UFile

Class M3UFile

beets/util/m3u.py:26–95  ·  view source on GitHub ↗

Reads and writes m3u or m3u8 playlist files.

Source from the content-addressed store, hash-verified

24
25
26class M3UFile:
27 """Reads and writes m3u or m3u8 playlist files."""
28
29 def __init__(self, path):
30 """``path`` is the absolute path to the playlist file.
31
32 The playlist file type, m3u or m3u8 is determined by 1) the ending
33 being m3u8 and 2) the file paths contained in the list being utf-8
34 encoded. Since the list is passed from the outside, this is currently
35 out of control of this class.
36 """
37 self.path = path
38 self.extm3u = False
39 self.media_list = []
40
41 def load(self):
42 """Reads the m3u file from disk and sets the object's attributes."""
43 pl_normpath = normpath(self.path)
44 try:
45 with open(syspath(pl_normpath), "rb") as pl_file:
46 raw_contents = pl_file.readlines()
47 except OSError as exc:
48 raise FilesystemError(
49 exc, "read", (pl_normpath,), traceback.format_exc()
50 )
51
52 self.extm3u = True if raw_contents[0].rstrip() == b"#EXTM3U" else False
53 for line in raw_contents[1:]:
54 if line.startswith(b"#"):
55 # Support for specific EXTM3U comments could be added here.
56 continue
57 self.media_list.append(normpath(line.rstrip()))
58 if not self.media_list:
59 raise EmptyPlaylistError
60
61 def set_contents(self, media_list, extm3u=True):
62 """Sets self.media_list to a list of media file paths.
63
64 Also sets additional flags, changing the final m3u-file's format.
65
66 ``media_list`` is a list of paths to media files that should be added
67 to the playlist (relative or absolute paths, that's the responsibility
68 of the caller). By default the ``extm3u`` flag is set, to ensure a
69 save-operation writes an m3u-extended playlist (comment "#EXTM3U" at
70 the top of the file).
71 """
72 self.media_list = media_list
73 self.extm3u = extm3u
74
75 def write(self):
76 """Writes the m3u file to disk.
77
78 Handles the creation of potential parent directories.
79 """
80 header = [b"#EXTM3U"] if self.extm3u else []
81 if not self.media_list:
82 raise EmptyPlaylistError
83 contents = header + self.media_list

Calls

no outgoing calls