mirror of
https://github.com/lutris/lutris
synced 2024-10-02 22:14:23 +00:00
Installer rewrite (WIP)
This commit is contained in:
parent
26f59c9bc7
commit
14a6881627
|
@ -3,6 +3,17 @@ Writing installers
|
|||
==================
|
||||
|
||||
|
||||
Displaying an 'Insert disc' dialog
|
||||
----------------------------------
|
||||
|
||||
The ``insert-disc`` command will display a message box to the user requesting
|
||||
him to insert the game's disc into the optical drive. A link to CDEmu homepage's
|
||||
and PPA will also be displayed if the program isn't detected on the machine,
|
||||
otherwise it will be replaced with a button to open gCDEmu.
|
||||
|
||||
An optional parameter ``message`` will override the default text if given.
|
||||
|
||||
|
||||
Moving files
|
||||
------------
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ from lutris.util.log import logger
|
|||
from lutris.util import http
|
||||
from lutris.util.strings import slugify
|
||||
from lutris.util.files import calculate_md5
|
||||
from lutris.util import extract
|
||||
from lutris.game import LutrisGame
|
||||
#from lutris.config import LutrisConfig
|
||||
from lutris.gui.dialogs import ErrorDialog, FileDialog
|
||||
|
@ -42,39 +43,6 @@ from lutris import settings
|
|||
from lutris.runners import import_task
|
||||
|
||||
|
||||
def unzip(filename, dest=None):
|
||||
"""Unzips a file"""
|
||||
command = ["unzip", '-o', filename]
|
||||
if dest:
|
||||
command = command + ['-d', dest]
|
||||
subprocess.call(command)
|
||||
|
||||
|
||||
def unrar(filename):
|
||||
"""Unrar a file"""
|
||||
|
||||
subprocess.call(["unrar", "x", filename])
|
||||
|
||||
|
||||
def untar(filename, dest=None, method='gzip'):
|
||||
"""Untar a file"""
|
||||
cwd = os.getcwd()
|
||||
if dest is None or not os.path.exists(dest):
|
||||
dest = cwd
|
||||
logger.debug("Will extract to %s" % dest)
|
||||
os.chdir(dest)
|
||||
if method == 'gzip':
|
||||
compression_flag = 'z'
|
||||
elif method == 'bzip2':
|
||||
compression_flag = 'j'
|
||||
else:
|
||||
compression_flag = ''
|
||||
cmd = "tar x%sf %s" % (compression_flag, filename)
|
||||
logger.debug(cmd)
|
||||
subprocess.Popen(cmd, shell=True)
|
||||
os.chdir(cwd)
|
||||
|
||||
|
||||
def run_installer(filename):
|
||||
"""Run an installer of .sh or .run type"""
|
||||
subprocess.call(["chmod", "+x", filename])
|
||||
|
@ -108,18 +76,24 @@ class ScriptInterpreter(object):
|
|||
for field in required_fields:
|
||||
if not self.script.get(field):
|
||||
self.errors.append("Missing field '%s'" % field)
|
||||
print self.errors
|
||||
return not bool(self.errors)
|
||||
|
||||
#def parse_config(self):
|
||||
# """ Reads the installer file. """
|
||||
# self.game = self.rules['name']
|
||||
# self.game_slug = os.path.basename(self.installer_path)[:-4]
|
||||
@classmethod
|
||||
def _map_command(cls, command_data):
|
||||
if isinstance(command_data, dict):
|
||||
command_name = command_data.keys()[0]
|
||||
command_params = command_data[command_name]
|
||||
else:
|
||||
command_name = command_data
|
||||
command_params = ""
|
||||
command_name = command_name.replace("-", "_")
|
||||
command_name = command_name.strip("_")
|
||||
if not hasattr(cls, command_name):
|
||||
raise ScriptingError("The command %s does not exists"
|
||||
% command_name)
|
||||
return getattr(cls, command_name), command_params
|
||||
|
||||
# self.actions = self.rules['installer']
|
||||
# self.lutris_config = LutrisConfig(runner=self.game_info['runner'])
|
||||
# return True
|
||||
def substitute(self, path_ref, path_type):
|
||||
def _substitute(self, path_ref, path_type):
|
||||
if not path_ref.startswith("$%s" % path_type):
|
||||
return
|
||||
if path_type == "GAMEDIR":
|
||||
|
@ -141,13 +115,13 @@ class ScriptInterpreter(object):
|
|||
)
|
||||
src_ref = params['src']
|
||||
src = (self.files.get(src_ref)
|
||||
or self.substitute(src_ref, 'CACHE')
|
||||
or self.substitute(src_ref, 'GAMEDIR'))
|
||||
or self._substitute(src_ref, 'CACHE')
|
||||
or self._substitute(src_ref, 'GAMEDIR'))
|
||||
if not src:
|
||||
raise ScriptingError("Wrong value for 'src' param", src_ref)
|
||||
dst_ref = params['dst']
|
||||
dst = (self.substitute(dst_ref, 'GAMEDIR')
|
||||
or self.substitute(dst_ref, 'HOME'))
|
||||
dst = (self._substitute(dst_ref, 'GAMEDIR')
|
||||
or self._substitute(dst_ref, 'HOME'))
|
||||
if not dst:
|
||||
raise ScriptingError("Wrong value for 'dst' param", dst_ref)
|
||||
return (src, dst)
|
||||
|
@ -167,6 +141,32 @@ class ScriptInterpreter(object):
|
|||
return False
|
||||
return True
|
||||
|
||||
def extract(self, data):
|
||||
""" Extracts a file, guessing the compression method """
|
||||
filename = self.files.get(data.get('file'))
|
||||
if not filename:
|
||||
logger.error("No file for '%s' in game files" % data)
|
||||
return False
|
||||
if not os.path.exists(filename):
|
||||
logger.error("%s does not exists" % filename)
|
||||
return False
|
||||
msg = "Extracting %s" % filename
|
||||
logger.debug(msg)
|
||||
self.set_status(msg)
|
||||
_, extension = os.path.splitext(filename)
|
||||
if extension == ".zip":
|
||||
extract.unzip(filename, self.game_dir)
|
||||
elif filename.endswith('.tgz') or filename.endswith('.tar.gz'):
|
||||
extract.untar(filename, None)
|
||||
elif filename.endswith('.tar.bz2'):
|
||||
extract.untar(filename, None, 'bzip2')
|
||||
else:
|
||||
logger.error("unrecognised file extension %s" % extension)
|
||||
return False
|
||||
|
||||
def _delete(self, data):
|
||||
print "Script has requested to delete %s" % data
|
||||
|
||||
|
||||
# pylint: disable=R0904
|
||||
class Installer(Gtk.Dialog):
|
||||
|
@ -425,7 +425,6 @@ class Installer(Gtk.Dialog):
|
|||
'insert-disc': self._insert_disc,
|
||||
'extract': self._extract,
|
||||
'move': self._move,
|
||||
'request_media': self._request_media,
|
||||
'run': self._run,
|
||||
'runner': self._runner_task,
|
||||
'check_md5': self._check_md5,
|
||||
|
@ -527,43 +526,6 @@ class Installer(Gtk.Dialog):
|
|||
print self.gamefiles
|
||||
print data
|
||||
|
||||
def _insert_disc(self, _data):
|
||||
print "Insert disc"
|
||||
|
||||
def _extract(self, data):
|
||||
""" Extracts a file, guessing the compression method """
|
||||
filename = self.gamefiles.get(data.get('file'))
|
||||
if not filename:
|
||||
logger.error("No file for '%s' in game files" % data)
|
||||
return False
|
||||
if not os.path.exists(filename):
|
||||
logger.error("%s does not exists" % filename)
|
||||
return False
|
||||
msg = "Extracting %s" % filename
|
||||
logger.debug(msg)
|
||||
self.status_label.set_text(msg)
|
||||
_, extension = os.path.splitext(filename)
|
||||
if extension == ".zip":
|
||||
unzip(filename, self.game_dir)
|
||||
elif filename.endswith('.tgz') or filename.endswith('.tar.gz'):
|
||||
untar(filename, None)
|
||||
elif filename.endswith('.tar.bz2'):
|
||||
untar(filename, None, 'bzip2')
|
||||
else:
|
||||
logger.error("unrecognised file extension %s" % extension)
|
||||
return False
|
||||
|
||||
def _delete(self, data):
|
||||
print "Script has requested to delete %s" % data
|
||||
|
||||
def _request_media(self, data):
|
||||
"""Prompt user to insert a removable media"""
|
||||
path = data.get('default', '')
|
||||
if os.path.exists(os.path.join(path, data['contains'])):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def _run(self, executable):
|
||||
"""Run an executable script"""
|
||||
exec_path = os.path.join(settings.CACHE_DIR, self.game_slug,
|
||||
|
|
|
@ -2,6 +2,7 @@ import os
|
|||
import tarfile
|
||||
import zipfile
|
||||
import gzip
|
||||
import subprocess
|
||||
from lutris.util.log import logger
|
||||
|
||||
|
||||
|
@ -42,3 +43,36 @@ def decompress_gz(file_path):
|
|||
dest_file.close()
|
||||
|
||||
return dest_path
|
||||
|
||||
|
||||
def unzip(filename, dest=None):
|
||||
"""Unzips a file"""
|
||||
command = ["unzip", '-o', filename]
|
||||
if dest:
|
||||
command = command + ['-d', dest]
|
||||
subprocess.call(command)
|
||||
|
||||
|
||||
def unrar(filename):
|
||||
"""Unrar a file"""
|
||||
|
||||
subprocess.call(["unrar", "x", filename])
|
||||
|
||||
|
||||
def untar(filename, dest=None, method='gzip'):
|
||||
"""Untar a file"""
|
||||
cwd = os.getcwd()
|
||||
if dest is None or not os.path.exists(dest):
|
||||
dest = cwd
|
||||
logger.debug("Will extract to %s" % dest)
|
||||
os.chdir(dest)
|
||||
if method == 'gzip':
|
||||
compression_flag = 'z'
|
||||
elif method == 'bzip2':
|
||||
compression_flag = 'j'
|
||||
else:
|
||||
compression_flag = ''
|
||||
cmd = "tar x%sf %s" % (compression_flag, filename)
|
||||
logger.debug(cmd)
|
||||
subprocess.Popen(cmd, shell=True)
|
||||
os.chdir(cwd)
|
||||
|
|
|
@ -17,3 +17,17 @@ class TestScriptInterpreter(TestCase):
|
|||
interpreter = ScriptInterpreter("")
|
||||
with self.assertRaises(ScriptingError):
|
||||
interpreter._get_move_paths({})
|
||||
|
||||
def test_get_command_returns_a_method(self):
|
||||
command, params = ScriptInterpreter._map_command({'move': 'whatever'})
|
||||
self.assertIn("bound method ScriptInterpreter.move", str(command))
|
||||
self.assertEqual(params, "whatever")
|
||||
|
||||
def test_get_command_doesnt_return_private_methods(self):
|
||||
""" """
|
||||
with self.assertRaises(ScriptingError) as ex:
|
||||
command, params = ScriptInterpreter._map_command(
|
||||
{'_substitute': 'foo'}
|
||||
)
|
||||
self.assertEqual(ex.exception.message,
|
||||
"The command substitute does not exists")
|
||||
|
|
Loading…
Reference in a new issue