mirror of
https://github.com/gryf/fs-uae-wrapper.git
synced 2025-12-19 12:28:12 +01:00
Added utility module with common functions
This commit is contained in:
@@ -1,11 +1,16 @@
|
|||||||
"""
|
"""
|
||||||
Misc utilities
|
Misc utilities
|
||||||
"""
|
"""
|
||||||
|
from distutils import spawn
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
try:
|
||||||
|
import configparser
|
||||||
|
except ImportError:
|
||||||
|
import ConfigParser as configparser
|
||||||
|
|
||||||
from fs_uae_wrapper.wrapper import WRAPPER_KEY
|
from fs_uae_wrapper import WRAPPER_KEY
|
||||||
|
|
||||||
|
|
||||||
ARCHIVERS = {'.tar': ['tar', 'xf'],
|
ARCHIVERS = {'.tar': ['tar', 'xf'],
|
||||||
@@ -20,6 +25,19 @@ ARCHIVERS = {'.tar': ['tar', 'xf'],
|
|||||||
'.lzx': ['unlzx']}
|
'.lzx': ['unlzx']}
|
||||||
|
|
||||||
|
|
||||||
|
def get_config_options(conf):
|
||||||
|
"""Read config file and return options as a dict"""
|
||||||
|
parser = configparser.SafeConfigParser()
|
||||||
|
try:
|
||||||
|
parser.read(conf)
|
||||||
|
except configparser.ParsingError:
|
||||||
|
# Configuration syntax is wrong
|
||||||
|
return None
|
||||||
|
|
||||||
|
return {key: val for section in parser.sections()
|
||||||
|
for key, val in parser.items(section)}
|
||||||
|
|
||||||
|
|
||||||
def extract_archive(arch_name):
|
def extract_archive(arch_name):
|
||||||
"""
|
"""
|
||||||
Extract provided archive to current directory
|
Extract provided archive to current directory
|
||||||
@@ -46,7 +64,7 @@ def extract_archive(arch_name):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def merge_options(configuration, wrapper_options):
|
def merge_wrapper_options(configuration, wrapper_options):
|
||||||
"""
|
"""
|
||||||
Merge dictionaries with wrapper options into one. Commandline options
|
Merge dictionaries with wrapper options into one. Commandline options
|
||||||
have precedence.
|
have precedence.
|
||||||
@@ -59,3 +77,114 @@ def merge_options(configuration, wrapper_options):
|
|||||||
options.update(wrapper_options)
|
options.update(wrapper_options)
|
||||||
|
|
||||||
return options
|
return options
|
||||||
|
|
||||||
|
|
||||||
|
def options_to_dict(commandline):
|
||||||
|
"""
|
||||||
|
"Parse" commandline switches and return them as dictionary
|
||||||
|
"""
|
||||||
|
options = {}
|
||||||
|
for option in commandline:
|
||||||
|
if option.startswith('--'):
|
||||||
|
if '=' in option:
|
||||||
|
key, val = option[2:].split('=')
|
||||||
|
options[key.strip()] = val.strip()
|
||||||
|
else:
|
||||||
|
options[option[2:].strip()] = '1'
|
||||||
|
|
||||||
|
return options
|
||||||
|
|
||||||
|
|
||||||
|
def merge_all_options(configuration, commandline):
|
||||||
|
"""
|
||||||
|
Merge dictionaries with wrapper options into one. Commandline options
|
||||||
|
have precedence.
|
||||||
|
"""
|
||||||
|
options = {}
|
||||||
|
for key, val in configuration:
|
||||||
|
options[key] = val
|
||||||
|
|
||||||
|
options.update(options_to_dict(commandline))
|
||||||
|
|
||||||
|
return options
|
||||||
|
|
||||||
|
|
||||||
|
def interpolate_variables(string, config_path, base=None):
|
||||||
|
"""
|
||||||
|
Interpolate variables used in fs-uae configuration files, like:
|
||||||
|
- $CONFIG
|
||||||
|
- $HOME
|
||||||
|
- $EXE
|
||||||
|
- $APP
|
||||||
|
- $DOCUMENTS
|
||||||
|
- $BASE
|
||||||
|
"""
|
||||||
|
|
||||||
|
if '$CONFIG' in string:
|
||||||
|
string = string.replace('$CONFIG',
|
||||||
|
os.path.dirname(os.path.abspath(config_path)))
|
||||||
|
if '$HOME' in string:
|
||||||
|
string = string.replace('$HOME', os.path.expandvars('$HOME'))
|
||||||
|
|
||||||
|
if '$EXE' in string:
|
||||||
|
string = string.replace('$EXE', spawn.find_executable('fs-uae'))
|
||||||
|
|
||||||
|
if '$APP' in string:
|
||||||
|
string = string.replace('$APP', spawn.find_executable('fs-uae'))
|
||||||
|
|
||||||
|
if '$DOCUMENTS' in string:
|
||||||
|
xdg_docs = os.getenv('XDG_DOCUMENTS_DIR',
|
||||||
|
os.path.expanduser('~/Documents'))
|
||||||
|
string = string.replace('$DOCUMENTS', xdg_docs)
|
||||||
|
|
||||||
|
if base:
|
||||||
|
if '$BASE' in string:
|
||||||
|
string = string.replace('$BASE', base)
|
||||||
|
|
||||||
|
return string
|
||||||
|
|
||||||
|
|
||||||
|
def get_config(conf_file):
|
||||||
|
"""
|
||||||
|
Try to find configuration files and collect data from it.
|
||||||
|
Will search for paths described in https://fs-uae.net/paths
|
||||||
|
- ~/Documents/FS-UAE/Configurations/Default.fs-uae
|
||||||
|
- ~/Documents/FS-UAE/Configurations/Host.fs-uae
|
||||||
|
- ~/FS-UAE/Configurations/Default.fs-uae
|
||||||
|
- ~/FS-UAE/Configurations/Host.fs-uae
|
||||||
|
- ~/.config/fs-uae/fs-uae.conf
|
||||||
|
- ./fs-uae.conf
|
||||||
|
- ./Config.fs-uae
|
||||||
|
"""
|
||||||
|
|
||||||
|
xdg_conf = os.getenv('XDG_CONFIG_HOME', os.path.expanduser('~/.config'))
|
||||||
|
user = os.path.expanduser('~/')
|
||||||
|
paths = ((os.path.join(xdg_conf, 'fs-uae/fs-uae.conf'),
|
||||||
|
os.path.join(xdg_conf, 'fs-uae/')),
|
||||||
|
(os.path.join(user,
|
||||||
|
'Documents/FS-UAE/Configurations/Default.fs-uae'),
|
||||||
|
os.path.join(user, 'Documents/FS-UAE')),
|
||||||
|
(os.path.join(user, 'FS-UAE/Configurations/Default.fs-uae'),
|
||||||
|
os.path.join(user, 'FS-UAE')))
|
||||||
|
|
||||||
|
for path, conf_dir in paths:
|
||||||
|
if os.path.exists(path):
|
||||||
|
config = get_config_options(path)
|
||||||
|
config.update(get_config_options(conf_file))
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
conf_dir = None
|
||||||
|
config = get_config_options(conf_file)
|
||||||
|
|
||||||
|
if 'base_dir' in config:
|
||||||
|
base_dir = interpolate_variables(config['base_dir'], conf_file)
|
||||||
|
host = os.path.join(base_dir, 'Configurations/Host.fs-uae')
|
||||||
|
|
||||||
|
if os.path.exists(host):
|
||||||
|
config.update(get_config_options(host))
|
||||||
|
# overwrite host options again via provided custom/relative conf
|
||||||
|
config.update(get_config_options(conf_file))
|
||||||
|
elif conf_dir:
|
||||||
|
config['_base_dir'] = conf_dir
|
||||||
|
|
||||||
|
return config
|
||||||
|
|||||||
68
tests/test_utils.py
Normal file
68
tests/test_utils.py
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from tempfile import mkstemp, mkdtemp
|
||||||
|
from unittest import TestCase
|
||||||
|
import shutil
|
||||||
|
|
||||||
|
from fs_uae_wrapper import utils
|
||||||
|
|
||||||
|
|
||||||
|
class TestUtils(TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
fd, self.fname = mkstemp()
|
||||||
|
self.dirname = mkdtemp()
|
||||||
|
os.close(fd)
|
||||||
|
self._argv = sys.argv[:]
|
||||||
|
sys.argv = ['fs-uae-wrapper']
|
||||||
|
self.curdir = os.path.abspath(os.curdir)
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
os.chdir(self.curdir)
|
||||||
|
shutil.rmtree(self.dirname)
|
||||||
|
os.unlink(self.fname)
|
||||||
|
sys.argv = self._argv[:]
|
||||||
|
|
||||||
|
def test_get_config_options(self):
|
||||||
|
|
||||||
|
configs = ["[conf]\nwrapper=foo\n",
|
||||||
|
"[conf]\n wrapper =foo\n",
|
||||||
|
"[conf]\n wrapper = foo\n",
|
||||||
|
"[conf]\nwrapper = foo \n"]
|
||||||
|
|
||||||
|
for cfg in configs:
|
||||||
|
with open(self.fname, 'w') as fobj:
|
||||||
|
fobj.write(cfg)
|
||||||
|
|
||||||
|
val = utils.get_config_options(self.fname)
|
||||||
|
self.assertDictEqual(val, {'wrapper': 'foo'})
|
||||||
|
|
||||||
|
with open(self.fname, 'w') as fobj:
|
||||||
|
fobj.write("[conf]\nwraper=foo\n")
|
||||||
|
conf = utils.get_config_options(self.fname)
|
||||||
|
self.assertDictEqual(conf, {'wraper': 'foo'})
|
||||||
|
|
||||||
|
with open(self.fname, 'w') as fobj:
|
||||||
|
fobj.write("[conf]\nwrapper\n")
|
||||||
|
conf = utils.get_config_options(self.fname)
|
||||||
|
self.assertIsNone(conf)
|
||||||
|
|
||||||
|
with open(self.fname, 'w') as fobj:
|
||||||
|
fobj.write("[conf]\nfullscreen = 1\n")
|
||||||
|
conf = utils.get_config_options(self.fname)
|
||||||
|
self.assertDictEqual(conf, {'fullscreen': '1'})
|
||||||
|
|
||||||
|
with open(self.fname, 'w') as fobj:
|
||||||
|
fobj.write("[conf]\nwrapper= = = something went wrong\n")
|
||||||
|
conf = utils.get_config_options(self.fname)
|
||||||
|
self.assertDictEqual(conf, {'wrapper': '= = something went wrong'})
|
||||||
|
|
||||||
|
with open(self.fname, 'w') as fobj:
|
||||||
|
fobj.write("[conf]\nwrapper = = \n")
|
||||||
|
conf = utils.get_config_options(self.fname)
|
||||||
|
self.assertDictEqual(conf, {'wrapper': '='})
|
||||||
|
|
||||||
|
with open(self.fname, 'w') as fobj:
|
||||||
|
fobj.write("[conf]\nwrapper = \n")
|
||||||
|
conf = utils.get_config_options(self.fname)
|
||||||
|
self.assertDictEqual(conf, {'wrapper': ''})
|
||||||
Reference in New Issue
Block a user