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

5

6 2
def get_dirs():
7
    """Returns a dict of all the known XDG Base Directories for the current user.
8

9
    The keys ``XDG_CACHE_DIR``, ``XDG_CONFIG_DIR``, and ``XDG_DATA_DIR`` is
10
    always available.
11

12
    Additional keys, like ``XDG_MUSIC_DIR``, may be available if the
13
    ``$XDG_CONFIG_DIR/user-dirs.dirs`` file exists and is parseable.
14

15
    See http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
16
    for the XDG Base Directory specification.
17
    """
18

19 2
    dirs = {
20
        "XDG_CACHE_DIR": pathlib.Path(
21
            os.getenv("XDG_CACHE_HOME", "~/.cache")
22
        ).expanduser(),
23
        "XDG_CONFIG_DIR": pathlib.Path(
24
            os.getenv("XDG_CONFIG_HOME", "~/.config")
25
        ).expanduser(),
26
        "XDG_DATA_DIR": pathlib.Path(
27
            os.getenv("XDG_DATA_HOME", "~/.local/share")
28
        ).expanduser(),
29
    }
30

31 2
    dirs.update(_get_user_dirs(dirs["XDG_CONFIG_DIR"]))
32

33 2
    return dirs
34

35

36 2
def _get_user_dirs(xdg_config_dir):
37
    """Returns a dict of XDG dirs read from
38
    ``$XDG_CONFIG_HOME/user-dirs.dirs``.
39

40
    This is used at import time for most users of :mod:`mopidy`. By rolling our
41
    own implementation instead of using :meth:`glib.get_user_special_dir` we
42
    make it possible for many extensions to run their test suites, which are
43
    importing parts of :mod:`mopidy`, in a virtualenv with global site-packages
44
    disabled, and thus no :mod:`glib` available.
45
    """
46

47 2
    dirs_file = xdg_config_dir / "user-dirs.dirs"
48

49 2
    if not dirs_file.exists():
50 2
        return {}
51

52 2
    data = dirs_file.read_bytes()
53 2
    data = b"[XDG_USER_DIRS]\n" + data
54 2
    data = data.replace(b"$HOME", bytes(pathlib.Path.home()))
55 2
    data = data.replace(b'"', b"")
56

57 2
    config = configparser.RawConfigParser()
58 2
    config.read_string(data.decode())
59

60 2
    result = {}
61 2
    for k, v in config.items("XDG_USER_DIRS"):
62 2
        if v is None:
63 0
            continue
64 2
        if isinstance(k, bytes):
65 0
            k = k.decode()
66 2
        result[k.upper()] = pathlib.Path(v).resolve()
67

68 2
    return result

Read our documentation on viewing source code .

Loading