xdg: Add XDG dir utils

This commit is contained in:
Stein Magnus Jodal 2015-04-07 23:43:32 +02:00
parent 20b457cc4a
commit 7bda4f835f
2 changed files with 125 additions and 0 deletions

56
mopidy/utils/xdg.py Normal file
View File

@ -0,0 +1,56 @@
from __future__ import absolute_import, unicode_literals
import ConfigParser
import io
import os
def get_dirs():
"""Returns a dict of all the known XDG Base Directories for the current user.
The keys ``XDG_CACHE_DIR``, ``XDG_CONFIG_DIR``, and ``XDG_DATA_DIR`` is
always available.
Additional keys, like ``XDG_MUSIC_DIR``, may be available if the
``$XDG_CONFIG_DIR/user-dirs.dirs`` file exists and is parseable.
See http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
for the XDG Base Directory specification.
"""
dirs = {
'XDG_CACHE_DIR': (
os.environ.get('XDG_CACHE_HOME') or
os.path.expanduser(b'~/.cache')),
'XDG_CONFIG_DIR': (
os.environ.get('XDG_CONFIG_HOME') or
os.path.expanduser(b'~/.config')),
'XDG_DATA_DIR': (
os.environ.get('XDG_DATA_HOME') or
os.path.expanduser(b'~/.local/share')),
}
dirs.update(_get_user_dirs(dirs['XDG_CONFIG_DIR']))
return dirs
def _get_user_dirs(xdg_config_dir):
dirs_file = os.path.join(xdg_config_dir, 'user-dirs.dirs')
if not os.path.exists(dirs_file):
return {}
with open(dirs_file, 'rb') as fh:
data = fh.read()
data = b'[XDG_USER_DIRS]\n' + data
data = data.replace(b'$HOME', os.path.expanduser(b'~'))
data = data.replace(b'"', b'')
config = ConfigParser.RawConfigParser()
config.readfp(io.BytesIO(data))
return {
k.decode('utf-8').upper(): os.path.abspath(v)
for k, v in config.items('XDG_USER_DIRS') if v is not None}

69
tests/utils/test_xdg.py Normal file
View File

@ -0,0 +1,69 @@
from __future__ import unicode_literals
import os
import mock
import pytest
from mopidy.utils import xdg
@pytest.yield_fixture
def environ():
patcher = mock.patch.dict(os.environ, clear=True)
yield patcher.start()
patcher.stop()
def test_cache_dir_default(environ):
assert xdg.get_dirs()['XDG_CACHE_DIR'] == os.path.expanduser(b'~/.cache')
def test_cache_dir_from_env(environ):
os.environ['XDG_CACHE_HOME'] = '/foo/bar'
assert xdg.get_dirs()['XDG_CACHE_DIR'] == '/foo/bar'
def test_config_dir_default(environ):
assert xdg.get_dirs()['XDG_CONFIG_DIR'] == os.path.expanduser(b'~/.config')
def test_config_dir_from_env(environ):
os.environ['XDG_CONFIG_HOME'] = '/foo/bar'
assert xdg.get_dirs()['XDG_CONFIG_DIR'] == '/foo/bar'
def test_data_dir_default(environ):
assert xdg.get_dirs()['XDG_DATA_DIR'] == os.path.expanduser(
b'~/.local/share')
def test_data_dir_from_env(environ):
os.environ['XDG_DATA_HOME'] = '/foo/bar'
assert xdg.get_dirs()['XDG_DATA_DIR'] == '/foo/bar'
def test_user_dirs(environ, tmpdir):
os.environ['XDG_CONFIG_HOME'] = str(tmpdir)
with open(os.path.join(str(tmpdir), 'user-dirs.dirs'), 'wb') as fh:
fh.write('# Some comments\n')
fh.write('XDG_MUSIC_DIR="$HOME/Music2"\n')
result = xdg.get_dirs()
assert result['XDG_MUSIC_DIR'] == os.path.expanduser(b'~/Music2')
assert 'XDG_DOWNLOAD_DIR' not in result
def test_user_dirs_when_no_dirs_file(environ, tmpdir):
os.environ['XDG_CONFIG_HOME'] = str(tmpdir)
result = xdg.get_dirs()
assert 'XDG_MUSIC_DIR' not in result
assert 'XDG_DOWNLOAD_DIR' not in result