somewhat heavy refactoring

This commit is contained in:
Mathieu Comandon 2012-04-30 00:27:12 +02:00
parent 968304b986
commit 18204cee27
23 changed files with 194 additions and 388 deletions

View file

@ -32,8 +32,7 @@ from lutris.installer import Installer
from lutris.config import check_config
from lutris.gui.lutriswindow import LutrisWindow
logger = logging.getLogger(__name__)
log.logger.name = "Lutris Gaming Platform"
log.logger.name = "Lutris"
def new_lutris_window():
""" Returns an instantiated LutrisWindow object. """
@ -48,7 +47,6 @@ def new_lutris_window():
window.finish_initializing(builder, DATA_PATH)
return window
check_config()
# Support for command line options.
parser = optparse.OptionParser(version="%prog %ver")
@ -70,6 +68,7 @@ if options.debug:
else:
log.logger.setLevel(log.logging.INFO)
if options.verbose:
log.logger.info("Verbose mode enabled")
console = log.logging.StreamHandler()
if options.debug:
console.setLevel(log.logging.DEBUG)
@ -81,6 +80,8 @@ if options.verbose:
console.setFormatter(formatter)
log.logger.addHandler(console)
check_config(force_wipe=True)
installer = False
game = None
if options.installer_file:

View file

@ -24,29 +24,49 @@ from os.path import join
import lutris.pga as pga
import lutris.constants as constants
from lutris.settings import PGA_PATH
from lutris.constants import CONFIG_EXTENSION, GAME_CONFIG_PATH
from lutris.util import log
from lutris.gconfwrapper import GconfWrapper
from lutris.settings import PGA_DB, CONFIG_DIR, DATA_DIR, CACHE_DIR
from lutris.constants import GAME_CONFIG_PATH
def check_config():
"""Check if configuration directories exists and create them if needed.
def register_handler():
gconf = GconfWrapper()
defaults = (('/desktop/gnome/url-handlers/lutris/command', "lutris '%s'"),
('/desktop/gnome/url-handlers/lutris/enabled', True),
('/desktop/gnome/url-handlers/lutris/needs-terminal', False),)
"""
config_paths = [constants.LUTRIS_CONFIG_PATH,
constants.runner_config_path,
constants.GAME_CONFIG_PATH,
constants.COVER_PATH,
constants.TMP_PATH,
constants.ICON_PATH,
constants.BANNER_PATH,
constants.LUTRIS_CACHE_PATH,
constants.LUTRIS_DATA_PATH]
for config_path in config_paths:
if not os.path.exists(config_path):
os.mkdir(config_path)
for key, value in defaults:
log.logger.debug("registering gconf key %s" % key)
gconf.set_key(key, value, override_type=True)
def check_config(force_wipe=False):
"""Check if initial configuration is correct."""
directories = [CONFIG_DIR,
CACHE_DIR,
DATA_DIR,
join(CONFIG_DIR, "runners"),
join(CONFIG_DIR, "games"),
join(DATA_DIR, "covers"),
join(DATA_DIR, "icons"),
join(DATA_DIR, "banners")]
if not os.path.exists(CONFIG_DIR) or force_wipe:
first_run = True
else:
first_run = False
for directory in directories:
if not os.path.exists(directory):
log.logger.debug("creating directory %s" % directory)
os.mkdir(directory)
if not os.path.isfile(PGA_DB) or force_wipe:
log.logger.debug("creating PGA database in %s" % PGA_DB)
if not os.path.isfile(PGA_PATH):
pga.create()
if first_run:
register_handler
class LutrisConfig():
@ -91,7 +111,7 @@ class LutrisConfig():
if self.game:
game_config_full_path = join(GAME_CONFIG_PATH,
self.game + CONFIG_EXTENSION)
self.game + ".yml")
if os.path.exists(game_config_full_path):
try:
content = file(game_config_full_path, 'r').read()
@ -108,7 +128,7 @@ class LutrisConfig():
if self.runner:
runner_config_full_path = join(constants.runner_config_path,
self.runner + CONFIG_EXTENSION)
self.runner + ".yml")
if os.path.exists(runner_config_full_path):
yaml_content = file(runner_config_full_path, 'r').read()
self.runner_config = yaml.load(yaml_content)
@ -164,7 +184,7 @@ class LutrisConfig():
logging.debug("removing %s", game_name)
os.remove(join(GAME_CONFIG_PATH,
game_name + CONFIG_EXTENSION))
game_name + ".yml"))
def is_valid(self):
"""Check the config data and return True if config is ok."""
@ -175,7 +195,7 @@ class LutrisConfig():
print "Error in %s config file : No runner" % self.game
return False
def save(self, runner_type=None):
def save(self, config_type=None):
"""Save configuration file
The way to save config files can be set by the type argument
@ -183,25 +203,24 @@ class LutrisConfig():
"""
self.update_global_config()
logging.debug("Saving config (type %s)", runner_type)
logging.debug("Saving config (type %s)", config_type)
logging.debug(self.config)
if runner_type is None:
runner_type = self.config_type
if config_type is None:
config_type = self.config_type
yaml_config = yaml.dump(self.config, default_flow_style=False)
if runner_type == "system":
if config_type == "system":
file(constants.system_config_full_path, "w").write(yaml_config)
elif runner_type == "runner":
elif config_type == "runner":
runner_config_path = join(constants.runner_config_path,
self.runner + CONFIG_EXTENSION)
self.runner + ".yml")
file(runner_config_path, "w").write(yaml_config)
elif runner_type == "game":
elif config_type == "game":
if not self.game:
self.game = self.config["runner"] \
+ "-" + self.config["realname"].replace(" ", "_")
game_config_path = join(GAME_CONFIG_PATH,
self.game.replace('/', '_') + \
CONFIG_EXTENSION)
self.game.replace('/', '_') + ".yml")
config_file = file(game_config_path, "w")
config_file.write(yaml_config)
return self.game

View file

@ -1,44 +0,0 @@
#!/usr/bin/python
# -*- coding:Utf-8 -*-
#
# Copyright (C) 2010 Mathieu Comandon <strider@strycore.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import os
import sys
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
try:
from lutris.gconfwrapper import GconfWrapper
GCONF_CAPABLE = True
except GConfBindingsUnavailable:
GCONF_CAPABLE = False
def register_lutris_handler():
if not GCONF_CAPABLE:
print "Can't find gconf bindings"
return
gconf = GconfWrapper()
defaults = (('/desktop/gnome/url-handlers/lutris/command', "lutris '%s'"),
('/desktop/gnome/url-handlers/lutris/enabled', True),
('/desktop/gnome/url-handlers/lutris/needs-terminal', False),)
for key, value in defaults:
if not gconf.has_key(key):
gconf.set_key(key, value, override_type = True)
if __name__ == '__main__':
register_lutris_handler()

View file

@ -57,9 +57,7 @@ if not exists(DATA_PATH):
print "DATA_PATH can't be found at : %s" % DATA_PATH
exit
lutris_icon_file = "media/logo.svg"
lutris_icon_path = join(DATA_PATH, lutris_icon_file)
LUTRIS_ICON_PATH = lutris_icon_path
LUTRIS_ICON = join(DATA_PATH, "media/logo.svg")
LUTRIS_CONFIG_PATH = join(BaseDirectory.xdg_config_home, 'lutris')
LUTRIS_DATA_PATH = join(BaseDirectory.xdg_data_home, 'lutris')
@ -72,5 +70,4 @@ GAME_CONFIG_PATH = join(LUTRIS_CONFIG_PATH, 'games')
COVER_PATH = join(LUTRIS_CONFIG_PATH, 'covers')
BANNER_PATH = join(LUTRIS_CONFIG_PATH, 'banners')
ICON_PATH = join(expanduser('~'), '.icons')
cache_path = LUTRIS_CACHE_PATH
TMP_PATH = join(LUTRIS_CACHE_PATH, 'tmp')

View file

@ -21,17 +21,12 @@
This class interacts with the window manager, xrandr, gconf, ...
"""
import gconf
import os.path
from subprocess import Popen, PIPE
from lutris.exceptions import GConfBindingsUnavailable
# Don't force to import gconf, some users might not have it.
try:
import gconf
from lutris.gconfwrapper import GconfWrapper
GCONF_CAPABLE = True
except GConfBindingsUnavailable:
GCONF_CAPABLE = False
from lutris.gconfwrapper import GconfWrapper
def make_compiz_rule(class_=None, title=None):
"""Return a string formated for the Window Rules plugin"""

View file

@ -21,7 +21,7 @@ import threading
from lutris.util import log
class DownloadStoppedException:
class DownloadStoppedException(Exception):
def __init__(self):
pass
@ -36,11 +36,10 @@ class Downloader(threading.Thread):
self.dest = dest
self.progress = 0
self.kill = None
print "init done"
def run(self):
"""Start the download."""
print "starting download"
log.debug("Download of %s starting" % self.url)
urllib.urlretrieve(self.url, self.dest, self._report_progress)
return True
@ -52,6 +51,4 @@ class Downloader(threading.Thread):
if self.kill is True:
raise DownloadStoppedException
except DownloadStoppedException:
pass
print "stopping download"
log.debug("stopping download")

View file

@ -1,23 +0,0 @@
#!/usr/bin/python
# -*- coding:Utf-8 -*-
#
# Copyright (C) 2010 Mathieu Comandon <strider@strycore.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
class GConfBindingsUnavailable(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)

View file

@ -16,12 +16,12 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import subprocess
import gobject
import os
import os.path
import time
import gtk
import time
import os.path
import gobject
import subprocess
from signal import SIGKILL
from lutris.runners import import_runner
@ -94,9 +94,7 @@ class LutrisGame(object):
self.load_success = self.load_config()
def load_config(self):
"""
Load the game's configuration.
"""
""" Load the game's configuration. """
self.game_config = LutrisConfig(game=self.name)
if self.game_config.is_valid():
self.runner_name = self.game_config["runner"]
@ -171,7 +169,7 @@ class LutrisGame(object):
logger.debug("Failed to set resolution %s"
% config["system"]["resolution"])
#Setting OSS Wrapper
#Setting OSS Wrapper
if "oss_wrapper" in config["system"]:
oss_wrapper = config["system"]["oss_wrapper"]

View file

@ -17,23 +17,19 @@
#
import os
import gconf
from glib import GError
from lutris.exceptions import GConfBindingsUnavailable
from lutris.util.log import logger
try:
import gconf
from glib import GError
except ImportError:
raise GConfBindingsUnavailable('Install python-gconf')
class GconfWrapper():
class GconfWrapper(object):
def __init__(self):
self.gconf_path = os.path.join(os.path.expanduser("~"), ".gconf")
self.client = gconf.client_get_default()
def has_key(self, key):
def has(self, key):
key = self.client.get_string(key)
if key:
return True

View file

@ -18,7 +18,7 @@ import os
import gtk.gdk
import lutris.constants
from lutris.constants import LUTRIS_ICON_PATH
from lutris.constants import LUTRIS_ICON
class AboutLutrisDialog(gtk.AboutDialog):
@ -48,8 +48,8 @@ class AboutLutrisDialog(gtk.AboutDialog):
#code for other initialization actions should be added here
self.set_position(gtk.WIN_POS_CENTER)
self.set_icon_from_file(lutris.constants.lutris_icon_path)
self.set_logo(gtk.gdk.pixbuf_new_from_file(LUTRIS_ICON_PATH))
self.set_icon_from_file(LUTRIS_ICON)
self.set_logo(gtk.gdk.pixbuf_new_from_file(LUTRIS_ICON))
self.set_name(lutris.constants.name)
self.set_version(lutris.constants.version)
self.set_copyright(lutris.constants.copyright)

View file

@ -131,7 +131,7 @@ class AddGameDialog(gtk.Dialog):
logging.debug(self.lutris_config.game_config)
if self.runner_class and realname:
game_identifier = self.lutris_config.save(runner_type="game")
game_identifier = self.lutris_config.save(config_type="game")
self.game_info = {"name": realname,
"runner": self.runner_class,
"id": game_identifier}

View file

@ -87,7 +87,7 @@ class EditGameConfigDialog(gtk.Dialog):
def edit_game(self, widget=None):
logging.debug(self.lutris_config.config)
self.lutris_config.save(runner_type="game")
self.lutris_config.save(config_type="game")
self.destroy()
def close(self, widget=None):

View file

@ -1,47 +0,0 @@
#!/usr/bin/python
# -*- coding:Utf-8 -*-
#
# Copyright (C) 2010 Mathieu Comandon <strider@strycore.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
"""Helpers for an Ubuntu application."""
__all__ = ['make_window',]
import os
import gtk
import gettext
from lutris.lutrisconfig import get_data_file
from gettext import gettext as _
gettext.textdomain('lutris')
def get_builder(builder_file_name):
"""Return a fully-instantiated gtk.Builder instance from specified ui
file
:param builder_file_name: The name of the builder file, without extension.
Assumed to be in the 'ui' directory under the data path.
"""
# Look for the ui file that describes the user interface.
ui_filename = get_data_file('ui', '%s.ui' % (builder_file_name,))
if not os.path.exists(ui_filename):
ui_filename = None
builder = gtk.Builder()
builder.set_translation_domain('lutris')
builder.add_from_file(ui_filename)
return builder

View file

@ -15,7 +15,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
"""Installer module"""
import os
import gtk
import yaml
@ -26,7 +26,7 @@ import platform
import subprocess
import lutris.constants
from os.path import join, exists, expanduser
from os.path import join, exists
from lutris.util import log
from lutris.util.strings import slugify
@ -35,7 +35,7 @@ from lutris.config import LutrisConfig
from lutris.gui.common import ErrorDialog, DirectoryDialog
from lutris.gui.widgets import DownloadProgressBox
from lutris.shortcuts import create_launcher
from lutris.constants import LUTRIS_CACHE_PATH, INSTALLER_URL, TMP_PATH,\
from lutris.constants import LUTRIS_CACHE_PATH, INSTALLER_URL, TMP_PATH, \
ICON_PATH, BANNER_PATH, GAME_CONFIG_PATH
@ -84,6 +84,7 @@ def reporthook(piece, received_bytes, total_size):
class Installer(gtk.Dialog):
""" Installer class """
def __init__(self, game, installer=False):
self.lutris_config = None # Internal game config
if not game:
@ -198,7 +199,6 @@ class Installer(gtk.Dialog):
urllib.urlretrieve(banner_url, banner_dest)
except IOError:
print "cant get banner to %s" % banner_dest
pass
icon_url = 'http://lutris.net/media/game_icons/%s.png' % self.game_slug
icon_path = join(ICON_PATH, "%s.png" % self.game_slug)
@ -206,7 +206,6 @@ class Installer(gtk.Dialog):
urllib.urlretrieve(icon_url, icon_path)
except IOError:
print "cant get icon"
pass
# Download installer if not already there.
if not os.path.exists(self.installer_path):
@ -238,6 +237,7 @@ class Installer(gtk.Dialog):
return success
def game_dir_set(self, widget=None):
"""Set the installation directory based on the user's choice"""
self.game_dir = widget.get_current_folder()
if os.path.exists(self.game_dir):
self.install_button.set_sensitive(True)
@ -248,15 +248,13 @@ class Installer(gtk.Dialog):
self.location_button.destroy()
self.install_button.set_sensitive(False)
self.current_file = 0
self.total_files = len(self.rules['files'])
for game_file in self.rules['files']:
self.download_game_file(game_file)
log.logger.debug("All files downloaded")
self.install()
def download_game_file(self, game_file):
"""Download a file referenced in the installer script"""
file_id = game_file.keys()[0]
# Game files can be either a string, containing the location of the
# file to fetch or a dict with the possible options :
@ -279,7 +277,6 @@ class Installer(gtk.Dialog):
log.logger.debug("Downloading %s" % url)
dest_path = self._download(url, filename, copyfile)
self.gamefiles[file_id] = dest_path
self.current_file += 1
return True
def install(self):
@ -299,8 +296,7 @@ class Installer(gtk.Dialog):
'move': self._move,
'delete': self.delete,
'request_media': self._request_media,
'run': self._run,
'locate': self._locate}
'run': self._run}
if action_name not in mappings.keys():
print "Action " + action_name + " not supported !"
return False
@ -427,8 +423,8 @@ class Installer(gtk.Dialog):
elif url.startswith("$ASK_DIR"):
#Ask the user where is located the file
basename = url[9:]
d = DirectoryDialog("Select location of file %s " % basename)
file_path = d.folder
dlg = DirectoryDialog("Select location of file %s " % basename)
file_path = dlg.folder
if copyfile is True:
location = os.path.join(file_path, basename)
shutil.copy(location, dest_dir)
@ -505,6 +501,7 @@ class Installer(gtk.Dialog):
return True
def _request_media(self, data):
"""Prompt user to insert a removable media"""
if 'default' in data:
path = data['default']
if os.path.exists(os.path.join(path, data['contains'])):
@ -513,6 +510,7 @@ class Installer(gtk.Dialog):
return False
def _run(self, data):
"""Run an executable script"""
exec_path = os.path.join(TMP_PATH, self.game_slug,
self.gamefiles[data['file']])
if not os.path.exists(exec_path):
@ -522,9 +520,7 @@ class Installer(gtk.Dialog):
os.popen('chmod +x %s' % exec_path)
subprocess.call([exec_path])
def _locate(self):
return None
def launch_game(self, widget, data=None):
def launch_game(self, **kwargs):
"""Launch a game after it's been installed"""
lutris_game = LutrisGame(self.game_slug)
lutris_game.play()

View file

@ -20,19 +20,26 @@
import sqlite3
from lutris.util.strings import slugify
from lutris.settings import PGA_PATH
from lutris.util import log
from lutris.settings import PGA_DB
def connect():
"""Connect to the local PGA database."""
return sqlite3.connect(PGA_PATH)
return sqlite3.connect(PGA_DB)
def create():
"""Create the local PGA database."""
log.logger.debug("Running CREATE statement...")
con = connect()
query = 'create table games ' + \
'(name text, slug text, machine text, runner text)'
query = """CREATE TABLE games (
id INTEGER PRIMARY KEY,
name TEXT,
slug TEXT,
machine TEXT,
runner TEXT,
lastplayed INTEGER)"""
con.execute(query)
con.commit()
con.close()

View file

@ -19,6 +19,8 @@
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
###############################################################################
"""Runner for the Steam platform"""
import os
import gtk
@ -26,10 +28,10 @@ from lutris.gui.common import QuestionDialog, DirectoryDialog
from lutris.runners.wine import wine
from lutris.config import LutrisConfig
class steam(wine):
"""Runner for the Steam platform."""
def __init__(self,settings=None):
def __init__(self, settings=None):
super(steam, self).__init__(settings)
self.executable = "Steam.exe"
self.package = None
@ -44,8 +46,8 @@ class steam(wine):
self.is_installable = False
self.appid = "26800"
self.game_options = [
{'option': 'appid', 'type': 'string', 'label': 'appid'},
{'option': 'args', 'type': 'string', 'label': 'arguments'}
{'option': 'appid', 'type': 'string', 'label': 'appid'},
{'option': 'args', 'type': 'string', 'label': 'arguments'}
]
if settings:
self.appid = settings['game']['appid']
@ -55,23 +57,22 @@ class steam(wine):
self.args = ""
def install(self):
q = QuestionDialog({
dlg = QuestionDialog({
'title': 'Installing Steam',
'question': 'Do you already have Steam on your computer ?'
})
if q.result == gtk.RESPONSE_NO:
if dlg.result == gtk.RESPONSE_NO:
print "!!! NOT IMPLEMENTED !!!"
d = DirectoryDialog('Where is located Steam ?')
dlg = DirectoryDialog('Where is located Steam ?')
config = LutrisConfig(runner='steam')
config.runner_config = {'system': {'game_path': d.folder }}
config.save(type='runner')
config.runner_config = {'system': {'game_path': dlg.folder}}
config.save(config_type='runner')
def is_installed(self):
"""Checks if wine is installed and
if the steam executable is on the harddrive
"""Checks if wine is installed and if the steam executable is on the
harddrive
"""
if not self.check_depends():
return False
@ -103,7 +104,7 @@ class steam(wine):
def get_appid_list(self):
self.game_list = []
os.chdir(os.path.join(self.game_path,"appcache"))
os.chdir(os.path.join(self.game_path, "appcache"))
max_counter = 10010
files = []
counter = 0
@ -117,36 +118,36 @@ class steam(wine):
steam_apps = []
for file in files:
if file.endswith(".vdf"):
test_file = open(file,"rb")
test_file = open(file, "rb")
appid = self.get_appid_from_filename(file)
appname = self.get_name(test_file)
if appname:
steam_apps.append((appid,appname,file))
steam_apps.append((appid, appname, file))
test_file.close()
steam_apps.sort()
steam_apps_file = open(
os.path.join(os.path.expanduser("~"),"steamapps.txt"),"w"
)
os.path.join(os.path.expanduser("~"), "steamapps.txt"), "w"
)
for steam_app in steam_apps:
#steam_apps_file.write("%d\t%s\n" % (steam_app[0],steam_app[1]))
#print ("%d\t%s\n" % (steam_app[0],steam_app[1]))
self.game_list.append((steam_app[0],steam_app[1]))
self.game_list.append((steam_app[0], steam_app[1]))
steam_apps_file.close()
def play(self):
if not self.check_depends():
return {'error': 'RUNNER_NOT_INSTALLED',
'runner': self.depends }
'runner': self.depends}
if not self.is_installed():
return {'error': 'RUNNER_NOT_INSTALLED',
'runner': self.__class__.__name__}
self.check_regedit_keys() #From parent wine runner
self.check_regedit_keys() # From parent wine runner
print self.game_path
print self.game_exe
steam_full_path = os.path.join(self.game_path, self.game_exe)
command = ['wine', '"' + steam_full_path + '"', '-applaunch', self.appid, self.args]
return {'command': command }
command = ['wine', '"%s"' % steam_full_path,
'-applaunch', self.appid, self.args]
return {'command': command}

View file

@ -1,100 +0,0 @@
#!/usr/bin/python
# -*- coding:Utf-8 -*-
#
# Copyright (C) 2010 Mathieu Comandon <strider@strycore.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import yaml
import urlparse
import os
import hashlib
import logging
import lutris.constants
from lutris.tool.url_tool import UrlTool
class LutrisInterpreter():
def __init__(self, filename=None):
self.valid_schemes = ('http', 'https', 'ftp')
self.url_tool = UrlTool()
self.files = {}
self.dirs = {}
self.dirs['cache'] = lutris.constants.cache_path
self.dirs['gamedir'] = '/home/strider/Jeux'
if filename:
self.load(filename)
def load(self, filename):
self.config = yaml.load(file(filename, 'r').read())
def get_files(self):
if not self.config:
return False
if 'files' in self.config:
for filename in self.config['files']:
file_id = filename.keys()[0]
file_path = filename[file_id]
url = urlparse.urlparse(file_path)
if url.scheme:
destfile = os.path.basename(url.path)
destpath = lutris.constants.cache_path + destfile
if not os.path.exists(destpath):
self.url_tool.save_to(destpath, file_path)
self.files[file_id] = destpath
else:
print 'not a url', file_id
def install(self):
if not 'installer' in self.config:
return False
for directive in self.config['installer']:
directive_name = directive.keys()[0]
print directive_name
if directive_name == 'md5_check':
self.md5_check(directive)
if directive_name == 'extract':
extract_info = directive['extract']
if 'newdir' in extract_info:
dest = os.path.join(self.dirs[extract_info['destination']],
extract_info['newdir'])
if not os.path.exists(dest):
os.mkdir(dest)
self.dirs[extract_info['newdir']] = dest
else:
dest = self.dirs[extract_info['destination']]
self.extract(extract_info['file'], dest)
def check_md5(self, file_id):
print 'checking ', self.files[file_id]
def extract(self, archive, dest, options={}):
if not 'method' in options:
method = 'zip'
else:
method = options['method']
print "extracting %s to %s " % (self.files[archive], dest)
command = "unzip %s -d %s" % (self.files[archive], dest)
os.system(command)
def move(self, source, destination):
os.move
if __name__ == '__main__':
filename = '/home/strider/Jeux/quake.lutris'
interpreter = LutrisInterpreter(filename)
interpreter.get_files()
interpreter.install()

View file

@ -1,9 +1,9 @@
from os.path import realpath, normpath, dirname, join, exists, expanduser
"""Settings module"""
from os.path import join
from xdg import BaseDirectory
import sys
LUTRIS_CONFIG_PATH = join(BaseDirectory.xdg_config_home, 'lutris')
LUTRIS_DATA_PATH = join(BaseDirectory.xdg_data_home, 'lutris')
LUTRIS_CACHE_PATH = join(BaseDirectory.xdg_cache_home, 'lutris')
CONFIG_DIR = join(BaseDirectory.xdg_config_home, 'lutris')
DATA_DIR = join(BaseDirectory.xdg_data_home, 'lutris')
CACHE_DIR = join(BaseDirectory.xdg_cache_home, 'lutris')
PGA_PATH = join(LUTRIS_DATA_PATH, 'pga.db')
PGA_DB = join(DATA_DIR, 'pga.db')

View file

@ -1,18 +1,16 @@
import sys
""" xdg desktop file creator """
import os
import shutil
from subprocess import Popen, PIPE
from xdg import BaseDirectory
# FIXME : why is this here ?
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
from subprocess import Popen, PIPE
from lutris.config import LutrisConfig
from lutris.constants import ICON_PATH, TMP_PATH
def create_launcher(game, desktop=False, menu=False):
""" Create desktop file """
config = LutrisConfig(game=game)
desktop_dir = Popen(['xdg-user-dir', 'DESKTOP'],
stdout=PIPE).communicate()[0]
@ -43,6 +41,3 @@ Categories=Game""" % (
shutil.copy(tmp_launcher_path,
os.path.join(menu_path, launcher_filename))
os.remove(tmp_launcher_path)
if __name__ == "__main__":
create_launcher("quake", desktop=True, menu=True)

View file

@ -15,16 +15,19 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
"""
Threading module, used to launch games while keeping Lutris operational.
"""
import sys
import logging
import gobject
import threading
import subprocess
import gobject
from os.path import exists
from signal import SIGKILL
from os import kill, killpg
from os import kill
class LutrisThread(threading.Thread):
@ -45,7 +48,7 @@ class LutrisThread(threading.Thread):
self.killswitch = killswitch
def run(self):
self.timer_id = gobject.timeout_add(2000, self.poke_process)
gobject.timeout_add(2000, self.poke_process)
logging.debug(self.command)
self.game_process = subprocess.Popen(self.command, shell=True,
stdout=subprocess.PIPE,
@ -64,8 +67,7 @@ class LutrisThread(threading.Thread):
return True
else:
if self.killswitch is not None and not exists(self.killswitch):
# How do be sure that pid + 1 is actually the game process ?
#self.game_process.terminate()
# How are we sure that pid + 1 is actually the game process ?
kill(self.game_process.pid + 1, SIGKILL)
self.pid = None
return False
@ -76,17 +78,3 @@ class LutrisThread(threading.Thread):
self.pid = None
return False
return True
class ThreadProcessReader(threading.Thread):
def __init__(self, stdout):
threading.Thread.__init__(self)
self.stdout = stdout
self.status = "running"
self.seconds_left = 0
def run(self):
seconds_max = 0
process_ended = False
while self.status == "running":
line = self.stdout.read(80)

View file

@ -8,8 +8,8 @@ print xdg_config_dirs
cache = xdg.Menu.parse("/etc/xdg/menus/applications.menu")
print cache
for entry in cache.getEntries():
#print entry
if str(entry) == 'Games':
print entry
if str(entry) in ('wine-wine'):
print("youpi")
for game in entry.getEntries():
print "============"

View file

@ -100,4 +100,3 @@ on Linux.""",
url='https://launchpad.net/lutris',
cmdclass={'install': InstallAndUpdateDataDirectory}
)

View file

@ -28,31 +28,62 @@ class TestGConfWrapper(unittest.TestCase):
self.gconf = GconfWrapper()
def runTest(self):
self.assertEqual(self.gconf.has_key('/apps/metacity/general/button_layout'), True)
self.assertEqual(self.gconf.has_key('/apps/metacity/general/bouton_disposition'), False)
self.assertEqual(self.gconf.has_key('/foo/bar'), False)
self.assertEqual(
self.gconf.has('/apps/metacity/general/button_layout'), True
)
self.assertEqual(
self.gconf.has('/apps/metacity/general/bouton_disposition'), False
)
self.assertEqual(self.gconf.has('/foo/bar'), False)
self.assertEqual(self.gconf.get_key('/foo/bar'), None)
self.assertEqual(self.gconf.get_key('/apps/metacity/general/raise_on_click'), True)
self.assertEqual(
self.gconf.get_key('/foo/bar'), None
)
self.assertEqual(
self.gconf.get_key('/apps/metacity/general/raise_on_click'), True
)
self.assertTrue(
self.gconf.set_key('/apps/metacity/general/auto_raise_delay',
500,
override_type=True))
self.assertEqual(self.gconf.get_key('/apps/metacity/general/auto_raise_delay'), 500)
self.gconf.set_key('/apps/metacity/general/auto_raise_delay',
500, override_type=True)
)
self.assertEqual(
self.gconf.get_key('/apps/metacity/general/auto_raise_delay'), 500
)
self.assertTrue(
self.gconf.set_key('/apps/metacity/general/raise_on_click', False)
)
self.assertEqual(
self.gconf.get_key('/apps/metacity/general/raise_on_click'), False
)
self.assertTrue(
self.gconf.set_key('/apps/metacity/general/raise_on_click', True)
)
self.assertEqual(
self.gconf.get_key('/apps/metacity/general/raise_on_click'), True
)
self.assertTrue(self.gconf.set_key('/apps/metacity/general/raise_on_click', False))
self.assertEqual(self.gconf.get_key('/apps/metacity/general/raise_on_click'), False)
self.assertTrue(self.gconf.set_key('/apps/metacity/general/raise_on_click', True))
self.assertEqual(self.gconf.get_key('/apps/metacity/general/raise_on_click'), True)
self.assertTrue(self.gconf.set_key('/apps/metacity/general/auto_raise_delay', 499))
self.assertEqual(self.gconf.get_key('/apps/metacity/general/auto_raise_delay'), 499)
self.assertFalse(self.gconf.set_key('/apps/metacity/general/auto_raise_delay', "Five hundred"))
self.assertTrue(self.gconf.set_key('/apps/metacity/general/auto_raise_delay', 500))
self.assertTrue(
self.gconf.set_key('/apps/metacity/general/auto_raise_delay', 499)
)
self.assertEqual(
self.gconf.get_key('/apps/metacity/general/auto_raise_delay'), 499
)
self.assertFalse(
self.gconf.set_key('/apps/metacity/general/auto_raise_delay',
"Five hundred")
)
self.assertTrue(
self.gconf.set_key('/apps/metacity/general/auto_raise_delay', 500)
)
print 'testing new keys'
self.assertTrue(self.gconf.set_key('/apps/lutris/tests/foo', "dressed like pazuzu", override_type = True))
self.assertEqual(self.gconf.get_key('/apps/lutris/tests/foo'), "dressed like pazuzu")
self.assertTrue(
self.gconf.set_key('/apps/lutris/tests/foo', "dressed like pazuzu",
override_type=True)
)
self.assertEqual(
self.gconf.get_key('/apps/lutris/tests/foo'), "dressed like pazuzu"
)
self.assertEqual(self.gconf.all_dirs('/apps/lutris'), ['tests'])
if __name__ == '__main__':