mopidy / mopidy
1 2
import os
2 2
import pathlib
3 2
import urllib
4

5 2
from mopidy import models
6 2
from mopidy.internal import path
7

8 2
from . import Extension
9

10

11 2
def path_to_uri(path, scheme=Extension.ext_name):
12
    """Convert file path to URI."""
13 2
    bytes_path = os.path.normpath(bytes(path))
14 2
    uripath = urllib.parse.quote_from_bytes(bytes_path)
15 2
    return urllib.parse.urlunsplit((scheme, None, uripath, None, None))
16

17

18 2
def uri_to_path(uri):
19
    """Convert URI to file path."""
20 2
    return path.uri_to_path(uri)
21

22

23 2
def name_from_path(path):
24
    """Extract name from file path."""
25 2
    name = bytes(pathlib.Path(path.stem))
26 2
    try:
27 2
        return name.decode(errors="replace")
28 0
    except UnicodeError:
29 0
        return None
30

31

32 2
def path_from_name(name, ext=None, sep="|"):
33
    """Convert name with optional extension to file path."""
34 2
    if ext:
35 2
        name = name.replace(os.sep, sep) + ext
36
    else:
37 2
        name = name.replace(os.sep, sep)
38 2
    return pathlib.Path(name)
39

40

41 2
def path_to_ref(path):
42 2
    return models.Ref.playlist(uri=path_to_uri(path), name=name_from_path(path))
43

44

45 2
def load_items(fp, basedir):
46 2
    refs = []
47 2
    name = None
48 2
    for line in filter(None, (line.strip() for line in fp)):
49 2
        if line.startswith("#"):
50 2
            if line.startswith("#EXTINF:"):
51 2
                name = line.partition(",")[2]
52 2
            continue
53 2
        elif not urllib.parse.urlsplit(line).scheme:
54 2
            path = basedir / line
55 2
            if not name:
56 2
                name = name_from_path(path)
57 2
            uri = path_to_uri(path, scheme="file")
58
        else:
59
            # TODO: ensure this is urlencoded
60 2
            uri = line  # do *not* extract name from (stream?) URI path
61 2
        refs.append(models.Ref.track(uri=uri, name=name))
62 2
        name = None
63 2
    return refs
64

65

66 2
def dump_items(items, fp):
67 2
    if any(item.name for item in items):
68 2
        print("#EXTM3U", file=fp)
69 2
    for item in items:
70 2
        if item.name:
71 2
            print(f"#EXTINF:-1,{item.name}", file=fp)
72
        # TODO: convert file URIs to (relative) paths?
73 2
        if isinstance(item.uri, bytes):
74 0
            print(item.uri.decode(), file=fp)
75
        else:
76 2
            print(item.uri, file=fp)
77

78

79 2
def playlist(path, items=None, mtime=None):
80 2
    if items is None:
81 2
        items = []
82 2
    return models.Playlist(
83
        uri=path_to_uri(path),
84
        name=name_from_path(path),
85
        tracks=[models.Track(uri=item.uri, name=item.name) for item in items],
86
        last_modified=(int(mtime * 1000) if mtime else None),
87
    )

Read our documentation on viewing source code .

Loading