diff --git a/lutris/__init__.py b/lutris/__init__.py index e69de29bb..bcd9570c7 100644 --- a/lutris/__init__.py +++ b/lutris/__init__.py @@ -0,0 +1 @@ +"""Main Lutris package""" diff --git a/lutris/config.py b/lutris/config.py index 15e8a642b..ad167865c 100644 --- a/lutris/config.py +++ b/lutris/config.py @@ -153,6 +153,7 @@ class LutrisConfig(): return value def get_system(self, key): + """Return the value of 'key' for system config""" try: value = self.config["system"][key] if str(value).lower() in ("false", "none", "no"): diff --git a/lutris/constants.py b/lutris/constants.py index a525b652b..fd156975f 100644 --- a/lutris/constants.py +++ b/lutris/constants.py @@ -20,31 +20,11 @@ from os.path import realpath, normpath, dirname, join, exists, expanduser from xdg import BaseDirectory import sys -name = "Lutris" -version = "0.2.6" -website = "http://lutris.net" protocol_version = 1 INSTALLER_URL = "http://lutris.net/media/installers/" #installer_prefix = "http://localhost:8000/media/installers/" CONFIG_EXTENSION = ".yml" license_id = 'GPL-3' -copyright = "(c) 2010 Lutris Gaming Platform" -authors = ["Mathieu Comandon "] -artists = ["Ludovic Soulié "] -license_text = """ - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - 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 . - """ LAUNCH_PATH = realpath(sys.path[0]) if LAUNCH_PATH.startswith('/usr'): @@ -56,7 +36,7 @@ else: DATA_PATH = dirname(lutris.__file__) if not exists(DATA_PATH): print "DATA_PATH can't be found at : %s" % DATA_PATH - exit + exit() LUTRIS_ICON = join(DATA_PATH, "media/logo.svg") LUTRIS_CONFIG_PATH = join(BaseDirectory.xdg_config_home, 'lutris') diff --git a/lutris/downloader.py b/lutris/downloader.py index 3f4dff5ff..485f3fb65 100644 --- a/lutris/downloader.py +++ b/lutris/downloader.py @@ -22,10 +22,12 @@ import threading from lutris.util import log + class DownloadStoppedException(Exception): """ Dummy exception for download canceled. """ def __init__(self): - pass + super(DownloadStoppedException, self).__init__() + class Downloader(threading.Thread): """Downloader class that doesn't block the program""" @@ -50,7 +52,7 @@ class Downloader(threading.Thread): old_progress = self.progress self.progress = ((piece * received_bytes)) / (total_size * 1.0) if self.progress - old_progress > 0.05: - log.logger.debug("Progress: %0.2f%" % self.progress * 100) + log.logger.debug("Progress: %0.2f%%", self.progress * 100) try: if self.kill is True: diff --git a/lutris/gui/aboutdialog.py b/lutris/gui/aboutdialog.py index 44dcbdcaa..5385c69eb 100644 --- a/lutris/gui/aboutdialog.py +++ b/lutris/gui/aboutdialog.py @@ -14,14 +14,20 @@ # with this program. If not, see . ### END LICENSE -import os -import gtk.gdk -import lutris.constants +"""About dialog""" +# pylint #37300 False positive F0401 on gtk.gdk import +# pylint: disable=F0401 +import gtk.gdk +import os + +from lutris import settings from lutris.constants import LUTRIS_ICON +# pylint: disable=R0904, R0901 class AboutLutrisDialog(gtk.AboutDialog): + """About dialog class""" __gtype_name__ = "AboutLutrisDialog" def __init__(self): @@ -50,13 +56,13 @@ class AboutLutrisDialog(gtk.AboutDialog): self.set_position(gtk.WIN_POS_CENTER) 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) - self.set_license(lutris.constants.license_text) - self.set_authors(lutris.constants.authors) - self.set_artists(lutris.constants.artists) - self.set_website(lutris.constants.website) + self.set_name(settings.PROJECT) + self.set_version(settings.VERSION) + self.set_copyright(settings.COPYRIGHT) + self.set_license(settings.LICENSE_TEXT) + self.set_authors(settings.AUTHORS) + self.set_artists(settings.ARTISTS) + self.set_website(settings.WEBSITE) def NewAboutLutrisDialog(data_path): diff --git a/lutris/gui/addgamedialog.py b/lutris/gui/addgamedialog.py index b7e5436f9..90476fa22 100644 --- a/lutris/gui/addgamedialog.py +++ b/lutris/gui/addgamedialog.py @@ -19,35 +19,38 @@ ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################### +"""Dialog to add a game manually""" + import gtk -import logging import lutris.runners from lutris.runners import import_runner from lutris.config import LutrisConfig +from lutris.util.log import logger from lutris.gui.gameconfigvbox import GameConfigVBox from lutris.gui.runnerconfigvbox import RunnerConfigVBox from lutris.gui.systemconfigvbox import SystemConfigVBox +# pylint: disable=R0904 class AddGameDialog(gtk.Dialog): + """ Add game dialog class""" def __init__(self, parent): - gtk.Dialog.__init__(self) + super(AddGameDialog, self).__init__() self.parent_window = parent - self.set_title("Add a new game") - self.set_size_request(600, 500) #Real name realname_hbox = gtk.HBox() - self.realname_label = gtk.Label("Name") - realname_hbox.pack_start(self.realname_label, False, False, 5) + realname_label = gtk.Label("Name") + realname_hbox.pack_start(realname_label, False, False, 5) self.realname_entry = gtk.Entry() realname_hbox.pack_start(self.realname_entry) self.vbox.pack_start(realname_hbox, False, False, 5) - self.lutris_config = LutrisConfig() + self.set_title("Add a new game") + self.set_size_request(600, 500) #Runner #get a list of available runners runner_liststore = gtk.ListStore(str, str) @@ -58,28 +61,28 @@ class AddGameDialog(gtk.Dialog): if hasattr(runner, "description"): description = runner.description else: - logging.debug("Please fix %s and add a description attribute"\ - % runner_cls) + logger.debug("Please fix %s and add a description attribute", + runner_cls) description = "" if hasattr(runner, "machine"): machine = runner.machine else: - logging.debug("Please fix % and add a machine attribute"\ - % runner_cls) + logger.debug("Please fix % and add a machine attribute", + runner_cls) machine = "" if runner.is_installed(): runner_liststore.append((machine + " (" + description + ")", runner_name)) - self.runner_combobox = gtk.ComboBox(runner_liststore) - self.runner_combobox.connect("changed", self.on_runner_changed) + runner_combobox = gtk.ComboBox(runner_liststore) + runner_combobox.connect("changed", self.on_runner_changed) cell = gtk.CellRendererText() - self.runner_combobox.pack_start(cell, True) - self.runner_combobox.add_attribute(cell, 'text', 0) - self.vbox.pack_start(self.runner_combobox, False, True, 5) + runner_combobox.pack_start(cell, True) + runner_combobox.add_attribute(cell, 'text', 0) + self.vbox.pack_start(runner_combobox, False, True, 5) - self.notebook = gtk.Notebook() - self.vbox.pack_start(self.notebook) + notebook = gtk.Notebook() + self.vbox.pack_start(notebook) #Game configuration self.game_config_vbox = gtk.Label("Select a runner from the list") @@ -87,7 +90,7 @@ class AddGameDialog(gtk.Dialog): self.conf_scroll_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) self.conf_scroll_window.add_with_viewport(self.game_config_vbox) - self.notebook.append_page(self.conf_scroll_window, + notebook.append_page(self.conf_scroll_window, gtk.Label("Game configuration")) #Runner configuration @@ -96,7 +99,7 @@ class AddGameDialog(gtk.Dialog): self.runner_scroll_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) self.runner_scroll_window.add_with_viewport(self.runner_config_vbox) - self.notebook.append_page(self.runner_scroll_window, + notebook.append_page(self.runner_scroll_window, gtk.Label("Runner configuration")) #System configuration @@ -105,40 +108,39 @@ class AddGameDialog(gtk.Dialog): self.system_scroll_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) self.system_scroll_window.add_with_viewport(self.system_config_vbox) - self.notebook.append_page(self.system_scroll_window, + notebook.append_page(self.system_scroll_window, gtk.Label("System configuration")) - #Action area cancel_button = gtk.Button(None, gtk.STOCK_CANCEL) add_button = gtk.Button(None, gtk.STOCK_ADD) self.action_area.pack_start(cancel_button) self.action_area.pack_start(add_button) cancel_button.connect("clicked", self.close) add_button.connect("clicked", self.add_game) - #Finish + self.show_all() self.run() - def add_game(self, button): + def add_game(self, _button): """OK button pressed in the Add Game Dialog""" #Get name realname = self.realname_entry.get_text() #Get runner self.lutris_config.config["realname"] = realname self.lutris_config.config["runner"] = self.runner_class - logging.debug("saving") - logging.debug(self.lutris_config.config) - logging.debug(self.lutris_config.game_config) + logger.debug("saving") + logger.debug(self.lutris_config.config) + logger.debug(self.lutris_config.game_config) if self.runner_class and realname: game_identifier = self.lutris_config.save(config_type="game") self.game_info = {"name": realname, "runner": self.runner_class, "id": game_identifier} - self.destroy() def on_runner_changed(self, widget): + """Action called when runner drop down is changed""" selected_runner = widget.get_active() scroll_windows_children = [self.conf_scroll_window.get_children(), self.runner_scroll_window.get_children(), @@ -148,15 +150,15 @@ class AddGameDialog(gtk.Dialog): child.destroy() if selected_runner == 0: - self.no_runner_selected() + no_runner_label = gtk.Label("Choose a runner from the list") + no_runner_label.show() + self.runner_scroll_window.add_with_viewport(no_runner_label) return self.runner_class = widget.get_model()[selected_runner][1] self.lutris_config = LutrisConfig(self.runner_class) - print self.runner_class - logging.debug("loading config before adding game : ") - logging.debug(self.lutris_config.config) - #Load game box + logger.debug("loading config before adding game : ") + logger.debug(self.lutris_config.config) self.game_config_vbox = GameConfigVBox(self.lutris_config, "game") self.conf_scroll_window.add_with_viewport(self.game_config_vbox) self.conf_scroll_window.show_all() @@ -171,10 +173,6 @@ class AddGameDialog(gtk.Dialog): self.system_scroll_window.add_with_viewport(self.system_config_vbox) self.system_scroll_window.show_all() - def close(self, widget=None, other=None): + def close(self, _widget=None, _other=None): + """Action received on dialog close""" self.destroy() - - def no_runner_selected(self): - no_runner_label = gtk.Label("Choose a runner from the list") - no_runner_label.show() - self.runner_scroll_window.add_with_viewport(no_runner_label) diff --git a/lutris/gui/common.py b/lutris/gui/common.py index 6bcd94e6a..ff57d6505 100644 --- a/lutris/gui/common.py +++ b/lutris/gui/common.py @@ -19,72 +19,71 @@ ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################### -""" Common message dialogs. """ +"""Common message dialogs""" -import sys -import os -import pygtk import gtk from lutris.gui.widgets import DownloadProgressBox -class NoticeDialog(object): +# pylint: disable=R0901, R0904 +class NoticeDialog(gtk.MessageDialog): """ Displays a message to the user. """ def __init__(self, message): - dialog = gtk.MessageDialog(buttons=gtk.BUTTONS_OK) - dialog.set_markup(message) - dialog.run() - dialog.destroy() + super(NoticeDialog, self).__init__(buttons=gtk.BUTTONS_OK) + self.set_markup(message) + self.run() + self.destroy() -class ErrorDialog(object): +# pylint: disable=R0904 +class ErrorDialog(gtk.MessageDialog): """ Displays an error message. """ def __init__(self, message): - dialog = gtk.MessageDialog(buttons=gtk.BUTTONS_OK) - dialog.set_markup(message) - dialog.run() - dialog.destroy() + super(ErrorDialog, self).__init__(buttons=gtk.BUTTONS_OK) + self.set_markup(message) + self.run() + self.destroy() -class QuestionDialog(object): +class QuestionDialog(gtk.MessageDialog): """ Asks a question. """ def __init__(self, settings): - dialog = gtk.MessageDialog( + super(QuestionDialog, self).__init__( type=gtk.MESSAGE_QUESTION, buttons=gtk.BUTTONS_YES_NO, message_format=settings['question'] ) - dialog.set_title(settings['title']) - self.result = dialog.run() - dialog.destroy() + self.set_title(settings['title']) + self.result = self.run() + self.destroy() -class DirectoryDialog: +class DirectoryDialog(gtk.FileChooserDialog): """Ask the user to select a directory""" - def __init__(self, message, default_path=None): - dialog = gtk.FileChooserDialog( + def __init__(self, message): + super(DirectoryDialog, self).__init__( title=message, action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER, buttons=(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE, - gtk.STOCK_OK, gtk.RESPONSE_OK) + gtk.STOCK_OK, gtk.RESPONSE_OK) ) - self.result = dialog.run() - self.folder = dialog.get_current_folder() - dialog.destroy() + self.result = self.run() + self.folder = self.get_current_folder() + self.destroy() +# pylint: disable=R0904 class DownloadDialog(gtk.Dialog): """ Dialog showing a download in progress. """ def __init__(self, url, dest): print "creating download dialog" gtk.Dialog.__init__(self, "Downloading file") - self.quit_gtk = False self.set_size_request(560, 100) self.connect('destroy', self.destroy_cb) params = {'url': url, 'dest': dest} self.download_progress_box = DownloadProgressBox(params) - self.download_progress_box.connect('complete', self.download_complete) + #self.download_progress_box.connect('complete', self.download_complete) label = gtk.Label('Downloading %s' % url) label.set_padding(0, 0) label.set_alignment(0.0, 1.0) @@ -94,13 +93,10 @@ class DownloadDialog(gtk.Dialog): self.download_progress_box.start() def destroy_cb(self, widget, data=None): + """Action triggered when window is closed""" self.download_cancel(None) self.destroy() - if self.quit_gtk is True: - gtk.main_quit() - def download_cancel(self, widget, data=None): + def download_cancel(self, _widget, _data=None): + """Action triggered when download is cancelled""" self.download_progress_box.cancel() - - def download_complete(self, widget, data=None): - print "download is complete" diff --git a/lutris/gui/configvbox.py b/lutris/gui/configvbox.py index 11c8818fb..4d1477749 100644 --- a/lutris/gui/configvbox.py +++ b/lutris/gui/configvbox.py @@ -18,18 +18,19 @@ ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################### -#Widget generators and their signal handlers +"""Widget generators and their signal handlers""" import gtk PADDING = 10 +# pylint: disable=R0904 class Label(gtk.Label): """ Standardised label for config vboxes""" - def __init__(self, str=None): + def __init__(self, message=None): """ Custom init of label """ - super(Label, self).__init__(str) + super(Label, self).__init__(message) self.set_size_request(200, 30) self.set_alignment(0.0, 0.5) self.set_line_wrap(True) diff --git a/lutris/gui/editgameconfigdialog.py b/lutris/gui/editgameconfigdialog.py index a6090c038..8e5518c60 100644 --- a/lutris/gui/editgameconfigdialog.py +++ b/lutris/gui/editgameconfigdialog.py @@ -19,6 +19,8 @@ ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################### +"""Game edition dialog""" + import logging import gtk from lutris.config import LutrisConfig @@ -27,7 +29,9 @@ from lutris.gui.runnerconfigvbox import RunnerConfigVBox from lutris.gui.systemconfigvbox import SystemConfigVBox +# pylint: disable=R0904 class EditGameConfigDialog(gtk.Dialog): + """Game config edit dialog""" def __init__(self, parent, game): self.parent_window = parent self.game = game @@ -85,10 +89,12 @@ class EditGameConfigDialog(gtk.Dialog): self.show_all() self.run() - def edit_game(self, widget=None): + def edit_game(self, _widget=None): + """Save the changes""" logging.debug(self.lutris_config.config) self.lutris_config.save(config_type="game") self.destroy() - def close(self, widget=None): + def close(self, _widget=None): + """Dialog destroy callback""" self.destroy() diff --git a/lutris/gui/gameconfigvbox.py b/lutris/gui/gameconfigvbox.py index 5e4364737..79d72dde0 100644 --- a/lutris/gui/gameconfigvbox.py +++ b/lutris/gui/gameconfigvbox.py @@ -19,16 +19,17 @@ ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################### -import gtk +"""Container for game config options""" -import lutris.runners +import gtk from lutris.runners import import_runner from lutris.gui.configvbox import ConfigVBox -from lutris.runners import import_runner +# pylint: disable=R0901,R0904 class GameConfigVBox(ConfigVBox): + """VBox for game options""" def __init__(self, lutris_config, caller): ConfigVBox.__init__(self, "game", caller) self.lutris_config = lutris_config diff --git a/lutris/gui/installerconfigvbox.py b/lutris/gui/installerconfigvbox.py index 1a95db238..6df42ea4f 100644 --- a/lutris/gui/installerconfigvbox.py +++ b/lutris/gui/installerconfigvbox.py @@ -19,11 +19,14 @@ ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################### +"""This is going away""" + import gtk from lutris.runners import import_runner from lutris.gui.configvbox import ConfigVBox +# pylint: disable=R0901,R0904 class InstallerConfigVBox(ConfigVBox): """This file is going to disapear anytime now.""" def __init__(self, lutris_config, caller): diff --git a/lutris/gui/installerdialog.py b/lutris/gui/installerdialog.py index df885a834..a80dc8eb9 100644 --- a/lutris/gui/installerdialog.py +++ b/lutris/gui/installerdialog.py @@ -19,6 +19,11 @@ ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################### +"""Dialog for game installer, probably shouldn't be here + + NEEDS REVIEW +""" + import gtk import logging import subprocess @@ -32,6 +37,7 @@ from lutris.gui.systemconfigvbox import SystemConfigVBox class InstallerDialog(gtk.Dialog): + """Installer dialog class""" def __init__(self, parent): gtk.Dialog.__init__(self) self.parent_window = parent @@ -58,14 +64,14 @@ class InstallerDialog(gtk.Dialog): if hasattr(runner, "description"): description = runner.description else: - logging.debug("Please fix %s and add a description attribute"\ - % runner_classname) + logging.debug("Please fix %s and add a description attribute", + runner_classname) description = "" if hasattr(runner, "machine"): machine = runner.machine else: - logging.debug("Please fix % and add a machine attribute"\ - % runner_classname) + logging.debug("Please fix %s and add a machine attribute", + runner_classname) machine = "" if runner.is_installed() and runner.is_installable: runner_liststore.append((machine + " (" + description + ")", @@ -145,6 +151,7 @@ class InstallerDialog(gtk.Dialog): self.destroy() def on_runner_changed(self, widget): + """action called on runner changed""" selected_runner = widget.get_active() scroll_windows_children = [self.installer_scroll_window.get_children(), self.runner_scroll_window.get_children(), @@ -176,7 +183,7 @@ class InstallerDialog(gtk.Dialog): self.system_scroll_window.add_with_viewport(self.system_config_vbox) self.system_scroll_window.show_all() - def close(self, widget=None, other=None): + def close(self, _widget=None, _other=None): self.destroy() def no_runner_selected(self): diff --git a/lutris/gui/runnersdialog.py b/lutris/gui/runnersdialog.py index 1b179225a..c7acebb0b 100644 --- a/lutris/gui/runnersdialog.py +++ b/lutris/gui/runnersdialog.py @@ -106,8 +106,7 @@ class RunnersDialog(gtk.Dialog): for runner in runner_list: # Get runner details - runner_class = import_runner(runner) - runner_instance = runner_class() + runner_instance = import_runner(runner) machine = runner_instance.machine description = runner_instance.description diff --git a/lutris/installer.py b/lutris/installer.py index 8183ffb32..e146b2381 100644 --- a/lutris/installer.py +++ b/lutris/installer.py @@ -36,7 +36,7 @@ from lutris.gui.common import ErrorDialog, DirectoryDialog from lutris.gui.widgets import DownloadProgressBox from lutris.shortcuts import create_launcher from lutris.settings import CONFIG_DIR, CACHE_DIR, DATA_DIR -from lutris.constants import INSTALLER_URL, GAME_CONFIG_PATH +from lutris.constants import INSTALLER_URL def unzip(filename, dest=None): @@ -83,21 +83,24 @@ def reporthook(piece, received_bytes, total_size): print "%d %%" % ((piece * received_bytes) * 100 / total_size) +# pylint: disable=R0904 class Installer(gtk.Dialog): - """ Installer class """ + """Installer class""" def __init__(self, game, installer=False): + super(Installer, self).__init__() self.lutris_config = None # Internal game config if not game: msg = "No game specified in this installer" log.logger.error(msg) ErrorDialog(msg) - return False + return self.game_name = game # Name of the game self.game_slug = slugify(self.game_name) self.description = False default_path = join(os.path.expanduser('~'), self.game_slug) log.logger.debug("default path set to %s " % default_path) self.game_dir = default_path + self.download_index = 0 self.rules = {} # Content of yaml file self.actions = [] self.errors = [] @@ -109,7 +112,6 @@ class Installer(gtk.Dialog): self.installer_path = join(CACHE_DIR, self.game_name + ".yml") else: self.installer_path = installer - self.location_button = gtk.FileChooserButton("Select folder") # FIXME: Wrong ! The runner should be loaded first in order to @@ -241,7 +243,7 @@ class Installer(gtk.Dialog): if os.path.exists(self.game_dir): self.install_button.set_sensitive(True) - def download_game_files(self, widget=None, data=None): + def download_game_files(self, _widget=None, _data=None): """ Runs the actions to complete the install. """ dest_dir = join(CACHE_DIR, "installer/%s" % self.game_slug) @@ -252,13 +254,12 @@ class Installer(gtk.Dialog): key, url = fileinfo.items()[0] filename = os.path.basename(url) self.gamefiles[key] = os.path.join(dest_dir, filename) - dest_file = os.path.join(dest_dir, filename) self.location_button.destroy() self.install_button.set_sensitive(False) - self.download_index = 0 self.process_downloads() def process_downloads(self): + """Download each file needed for the game""" if self.download_index < len(self.rules["files"]): log.logger.info( "Downloading file %d of %d" % (self.download_index + 1, @@ -270,7 +271,7 @@ class Installer(gtk.Dialog): log.logger.debug("All files downloaded") self.install() - def download_complete(self, widget, data): + def download_complete(self, _widget, _data): """Action called on a completed download""" self.download_index += 1 self.process_downloads() @@ -299,6 +300,7 @@ class Installer(gtk.Dialog): self._download(url, filename, copyfile) def install(self): + """Actual game installation""" log.logger.debug("Running installation") if self.download_progress is not None: @@ -516,7 +518,7 @@ class Installer(gtk.Dialog): os.popen('chmod +x %s' % exec_path) subprocess.call([exec_path]) - def launch_game(self, widget, data=None): + def launch_game(self, _widget, _data=None): """Launch a game after it's been installed""" lutris_game = LutrisGame(self.game_slug) lutris_game.play() diff --git a/lutris/runners/__init__.py b/lutris/runners/__init__.py index ff11b07fa..952b914e9 100644 --- a/lutris/runners/__init__.py +++ b/lutris/runners/__init__.py @@ -14,4 +14,8 @@ def import_runner(runner_name, config=None): logger.error("Invalid runner %s" % runner) logger.error(msg) - return runner_cls(config) + try: + instance = runner_cls(config) + except: + print runner_name + return instance diff --git a/lutris/runners/dolphin.py b/lutris/runners/dolphin.py index f53bbd982..d6a421969 100644 --- a/lutris/runners/dolphin.py +++ b/lutris/runners/dolphin.py @@ -33,7 +33,7 @@ class dolphin(Runner): Download link : http://dolphin.jcf129.com/dolphin-2.0.i686.tar.bz2 ppa : ppa:glennric/dolphin-emu """ - def __init__(self): + def __init__(self, config): """ class initialization """ super(dolphin, self).__init__() self.package = "dolphin-emu" diff --git a/lutris/runners/hatari.py b/lutris/runners/hatari.py index 02fd24b49..c97d6e94d 100644 --- a/lutris/runners/hatari.py +++ b/lutris/runners/hatari.py @@ -34,8 +34,6 @@ class hatari(Runner): self.package = "hatari" self.executable = "hatari" self.machine = "Atari ST computers" - self.is_installable = True - self.description = "AtariST emulator." self.settings = settings self.game_options = [ {"option": "disk-a", "type":"single", "label": "Floppy Disk A"}, @@ -125,15 +123,14 @@ class hatari(Runner): } else: return {'error': 'NO_BIOS'} - self.error_messages = self.error_messages + ["TOS path not set."] if "disk-a" in game_settings: - self.diska = game_settings['disk-a'] - self.arguments = self.arguments + ["--disk-a \"%s\"" % self.diska] + diska = game_settings['disk-a'] + self.arguments = self.arguments + ["--disk-a \"%s\"" % diska] if not self.is_installed(): return {'error': 'RUNNER_NOT_INSTALLED', 'runner': self.__class__.__name__} - if not os.path.exists(self.diska): - return {'error': 'FILE_NOT_FOUND', 'file': self.diska} + if not os.path.exists(diska): + return {'error': 'FILE_NOT_FOUND', 'file': diska} command = [self.executable] + self.arguments return {"command": command} diff --git a/lutris/runners/jzintv.py b/lutris/runners/jzintv.py index 29e3f0867..3fe07c0a0 100644 --- a/lutris/runners/jzintv.py +++ b/lutris/runners/jzintv.py @@ -19,46 +19,59 @@ ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################### +'''Runner for intellivision games''' + from lutris.runners.runner import Runner import os.path + # pylint: disable=C0103 class jzintv(Runner): - '''Runner for intellivision games''' + """Intellivision Emulator""" - def __init__(self,settings = None): + def __init__(self, settings=None): '''Constructor''' + super(jzintv, self).__init__() self.package = "jzintv" self.executable = "jzintv" self.machine = "Intellivision" #jzintv is not yet available as a package in Debian and Ubuntu, #it requires some packaging self.is_installable = False - - - self.description = "Intellivision Emulator" - - self.game_options = [{"option":"rom","type":"single","label":"Rom File"}] - self.runner_options = [{"option": "bios_path", "type":"directory_chooser", "label":"Bios Path"}, - {"option": "fullscreen", "type":"bool", "label":"Fullscreen"}, - ] + self.game_options = [{ + "option":"rom", + "type":"single", + "label":"Rom File" + }] + self.runner_options = [ + { + "option": "bios_path", + "type": "directory_chooser", + "label": "Bios Path" + }, + { + "option": "fullscreen", + "type": "bool", + "label":"Fullscreen" + } + ] self.arguments = [] if settings: if "fullscreen" in settings["jzintv"]: if settings["jzintv"]["fullscreen"]: self.arguments = self.arguments + ["-f"] if "bios_path" in settings["jzintv"]: - self.arguments = self.arguments + ["--execimg=\"%s/exec.bin\"" % settings["jzintv"]["bios_path"] ] - self.arguments = self.arguments + ["--gromimg=\"%s/grom.bin\"" % settings["jzintv"]["bios_path"] ] + self.arguments += ["--execimg=\"%s/exec.bin\"" % \ + settings["jzintv"]["bios_path"]] + self.arguments += ["--gromimg=\"%s/grom.bin\"" % \ + settings["jzintv"]["bios_path"]] else: self.error_message = "Bios path not set" romdir = os.path.dirname(settings["game"]["rom"]) romfile = os.path.basename(settings["game"]["rom"]) - self.arguments = self.arguments + ["--rom-path=\"%s\"" % romdir+"/"] - self.arguments = self.arguments + ["\""+romfile+"\""] - + self.arguments += ["--rom-path=\"%s/\"" % romdir] + self.arguments += ["\"%s\"" % romfile] def play(self): command = [self.executable] + self.arguments return command - diff --git a/lutris/runners/linux.py b/lutris/runners/linux.py index df6d6e5ce..b034f9453 100644 --- a/lutris/runners/linux.py +++ b/lutris/runners/linux.py @@ -1,5 +1,3 @@ -import logging -import os.path # -*- coding:Utf-8 -*- ############################################################################### ## Lutris @@ -21,42 +19,60 @@ import os.path ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################### +""" Linux runner """ + import os import stat +import os.path +import logging from lutris.runners.runner import Runner + # pylint: disable=C0103 class linux(Runner): - def __init__(self,settings=None): - self.description = "Runs native games" + """Runs native games""" + def __init__(self, config=None): + super(linux, self).__init__() self.machine = "Linux games" - self.is_installable = True self.ld_preload = None - self.installer_options = [{"option": "installer","type": "single","label": "Executable"}] - - self.game_options = [ {"option": "exe", "type":"single", "label":"Executable"}, - {"option": "args", "type": "string", "label": "Arguments"}, - {"option": "ld_preload", "type": "single", "label": "Preload library"}] + self.game_path = None + self.installer_options = [{ + "option": "installer", + "type": "single", + "label": "Executable" + }] + self.game_options = [ + { + "option": "exe", + "type":"single", + "label":"Executable" + }, + { + "option": "args", + "type": "string", + "label": "Arguments" + }, + { + "option": "ld_preload", + "type": "single", + "label": "Preload library" + } + ] self.runner_options = [] - if settings: - self.executable = settings["game"]["exe"] - if 'args' in settings['game']: - self.args = settings['game']['args'] - else: - self.args = None - if 'ld_preload' in settings['game']: - self.ld_preload = settings['game']['ld_preload'] + self.config = config - def get_install_command(self,installer_path): + def get_install_command(self, installer_path): + """ Launch install script (usually .bin or .sh) """ #Check if installer exists if not os.path.exists(installer_path): raise IOError #Check if script is executable and make it executable if not - if not os.access(installer_path,os.X_OK): + if not os.access(installer_path, os.X_OK): logging.debug("%s is not executable, setting it executable") - os.chmod(installer_path, stat.S_IXUSR | stat.S_IRUSR | stat.S_IWUSR) + os.chmod(installer_path, + stat.S_IXUSR | stat.S_IRUSR | stat.S_IWUSR) return "x-terminal-emulator -e %s" % installer_path @@ -65,15 +81,20 @@ class linux(Runner): return True def play(self): - self.game_path = os.path.dirname(self.executable) - if not os.path.exists(self.executable): - return {'error': 'FILE_NOT_FOUND', 'file': self.executable } + executable = self.config["game"]["exe"] + if 'args' in self.config['game']: + args = self.config['game']['args'] + else: + args = "" + if 'ld_preload' in self.config['game']: + self.ld_preload = self.config['game']['ld_preload'] + self.game_path = os.path.dirname(executable) + if not os.path.exists(executable): + return {'error': 'FILE_NOT_FOUND', 'file': executable} command = [] if self.ld_preload: command.append("LD_PRELOAD=%s " % self.ld_preload) - command.append("./%s" % os.path.basename(self.executable)) - if self.args: - for arg in self.args.split(): - command.append(arg) - - return {'command': command } + command.append("./%s" % os.path.basename(executable)) + for arg in args.split(): + command.append(arg) + return {'command': command} diff --git a/lutris/runners/mednafen.py b/lutris/runners/mednafen.py index 5516f0d91..98db35cc5 100644 --- a/lutris/runners/mednafen.py +++ b/lutris/runners/mednafen.py @@ -19,6 +19,8 @@ ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################### +""" Runner for multi-consoles (8bit mainly) """ + import os import subprocess @@ -29,14 +31,14 @@ from lutris.util.log import logger # pylint: disable=C0103 class mednafen(Runner): + """Use Mednafen""" def __init__(self, settings=None): + super(mednafen, self).__init__() self.executable = "mednafen" - self.is_installable = True self.machine = """ Atari Lynx, Game Boy (Color), GameBoy Advance, NES, PC Engine(TurboGrafx 16), SuperGrafx, Neo Geo Pocket (Color), PC-FX, and WonderSwan (Color)""" - self.description = """Use Mednafen""" self.package = "mednafen" machine_choices = [("NES", "nes"), ("PC Engine", "pce"), @@ -60,19 +62,11 @@ class mednafen(Runner): "type": "bool", "label": "Fullscreen" }] - - if settings: - self.rom = settings["game"]["rom"] - self.machine = settings["game"]["machine"] - #Defaults - self.fullscreen = "1" - - if "mednafen" in settings.config: - if "fs" in settings.config["mednafen"]: - if not settings.config["mednafen"]["fs"]: - self.fullscreen = "0" + self.settings = settings def find_joysticks(self): + """ Detect connected joysticks and return their ids """ + joy_ids = [] if not self.is_installed: return False output = subprocess.Popen(["mednafen", "dummy"], @@ -92,87 +86,89 @@ class mednafen(Runner): index = joy.find("Unique ID:") joy_id = joy[index + 11:] logger.debug('Joystick found id %s ' % joy_id) - self.joy_ids.append(joy_id) + joy_ids.append(joy_id) + return joy_ids - def set_joystick_controls(self): + def set_joystick_controls(self, joy_ids): + """ Setup joystick mappings per machine """ nes_controls = [ "-nes.input.port1.gamepad.a", - "\"joystick " + self.joy_ids[0] + " 00000001\"", + "\"joystick " + joy_ids[0] + " 00000001\"", "-nes.input.port1.gamepad.b", - "\"joystick " + self.joy_ids[0] + " 00000002\"", + "\"joystick " + joy_ids[0] + " 00000002\"", "-nes.input.port1.gamepad.start", - "\"joystick " + self.joy_ids[0] + " 00000009\"", + "\"joystick " + joy_ids[0] + " 00000009\"", "-nes.input.port1.gamepad.select", - "\"joystick " + self.joy_ids[0] + " 00000008\"", + "\"joystick " + joy_ids[0] + " 00000008\"", "-nes.input.port1.gamepad.up", - "\"joystick " + self.joy_ids[0] + " 0000c001\"", + "\"joystick " + joy_ids[0] + " 0000c001\"", "-nes.input.port1.gamepad.down", - "\"joystick " + self.joy_ids[0] + " 00008001\"", + "\"joystick " + joy_ids[0] + " 00008001\"", "-nes.input.port1.gamepad.left", - "\"joystick " + self.joy_ids[0] + " 0000c000\"", + "\"joystick " + joy_ids[0] + " 0000c000\"", "-nes.input.port1.gamepad.right", - "\"joystick " + self.joy_ids[0] + " 00008000\"" + "\"joystick " + joy_ids[0] + " 00008000\"" ] gba_controls = [ "-gba.input.builtin.gamepad.a", - "\"joystick " + self.joy_ids[0] + " 00000001\"", + "\"joystick " + joy_ids[0] + " 00000001\"", "-gba.input.builtin.gamepad.b", - "\"joystick " + self.joy_ids[0] + " 00000002\"", + "\"joystick " + joy_ids[0] + " 00000002\"", "-gba.input.builtin.gamepad.shoulder_r", - "\"joystick " + self.joy_ids[0] + " 00000007\"", + "\"joystick " + joy_ids[0] + " 00000007\"", "-gba.input.builtin.gamepad.shoulder_l", - "\"joystick " + self.joy_ids[0] + " 00000006\"", + "\"joystick " + joy_ids[0] + " 00000006\"", "-gba.input.builtin.gamepad.start", - "\"joystick " + self.joy_ids[0] + " 00000009\"", + "\"joystick " + joy_ids[0] + " 00000009\"", "-gba.input.builtin.gamepad.select", - "\"joystick " + self.joy_ids[0] + " 00000008\"", + "\"joystick " + joy_ids[0] + " 00000008\"", "-gba.input.builtin.gamepad.up", - "\"joystick " + self.joy_ids[0] + " 0000c001\"", + "\"joystick " + joy_ids[0] + " 0000c001\"", "-gba.input.builtin.gamepad.down", - "\"joystick " + self.joy_ids[0] + " 00008001\"", + "\"joystick " + joy_ids[0] + " 00008001\"", "-gba.input.builtin.gamepad.left", - "\"joystick " + self.joy_ids[0] + " 0000c000\"", + "\"joystick " + joy_ids[0] + " 0000c000\"", "-gba.input.builtin.gamepad.right", - "\"joystick " + self.joy_ids[0] + " 00008000\"" + "\"joystick " + joy_ids[0] + " 00008000\"" ] gb_controls = [ "-gb.input.builtin.gamepad.a", - "\"joystick " + self.joy_ids[0] + " 00000001\"", + "\"joystick " + joy_ids[0] + " 00000001\"", "-gb.input.builtin.gamepad.b", - "\"joystick " + self.joy_ids[0] + " 00000002\"", + "\"joystick " + joy_ids[0] + " 00000002\"", "-gb.input.builtin.gamepad.start", - "\"joystick " + self.joy_ids[0] + " 00000009\"", + "\"joystick " + joy_ids[0] + " 00000009\"", "-gb.input.builtin.gamepad.select", - "\"joystick " + self.joy_ids[0] + " 00000008\"", + "\"joystick " + joy_ids[0] + " 00000008\"", "-gb.input.builtin.gamepad.up", - "\"joystick " + self.joy_ids[0] + " 0000c001\"", + "\"joystick " + joy_ids[0] + " 0000c001\"", "-gb.input.builtin.gamepad.down", - "\"joystick " + self.joy_ids[0] + " 00008001\"", + "\"joystick " + joy_ids[0] + " 00008001\"", "-gb.input.builtin.gamepad.left", - "\"joystick " + self.joy_ids[0] + " 0000c000\"", + "\"joystick " + joy_ids[0] + " 0000c000\"", "-gb.input.builtin.gamepad.right", - "\"joystick " + self.joy_ids[0] + " 00008000\"" + "\"joystick " + joy_ids[0] + " 00008000\"" ] pce_controls = [ "-pce.input.port1.gamepad.i", - "\"joystick " + self.joy_ids[0] + " 00000001\"", + "\"joystick " + joy_ids[0] + " 00000001\"", "-pce.input.port1.gamepad.ii", - "\"joystick " + self.joy_ids[0] + " 00000002\"", + "\"joystick " + joy_ids[0] + " 00000002\"", "-pce.input.port1.gamepad.run", - "\"joystick " + self.joy_ids[0] + " 00000009\"", + "\"joystick " + joy_ids[0] + " 00000009\"", "-pce.input.port1.gamepad.select", - "\"joystick " + self.joy_ids[0] + " 00000008\"", + "\"joystick " + joy_ids[0] + " 00000008\"", "-pce.input.port1.gamepad.up", - "\"joystick " + self.joy_ids[0] + " 0000c001\"", + "\"joystick " + joy_ids[0] + " 0000c001\"", "-pce.input.port1.gamepad.down", - "\"joystick " + self.joy_ids[0] + " 00008001\"", + "\"joystick " + joy_ids[0] + " 00008001\"", "-pce.input.port1.gamepad.left", - "\"joystick " + self.joy_ids[0] + " 0000c000\"", + "\"joystick " + joy_ids[0] + " 0000c000\"", "-pce.input.port1.gamepad.right", - "\"joystick " + self.joy_ids[0] + " 00008000\"" + "\"joystick " + joy_ids[0] + " 00008000\"" ] if self.machine == "pce": @@ -185,25 +181,34 @@ class mednafen(Runner): controls = gb_controls else: controls = [] - for control in controls: - self.options.append(control) + return controls def play(self): """Runs the game""" + rom = self.settings["game"]["rom"] + machine = self.settings["game"]["machine"] + #Defaults + fullscreen = "1" + + if "mednafen" in self.settings.config: + if "fs" in self.settings.config["mednafen"]: + if not self.settings.config["mednafen"]["fs"]: + fullscreen = "0" resolution = get_current_resolution() (resolutionx, resolutiony) = resolution.split("x") xres = str(resolutionx) yres = str(resolutiony) - self.options = ["-fs", self.fullscreen, - "-" + self.machine + ".xres", xres, - "-" + self.machine + ".yres", yres, - "-" + self.machine + ".stretch", "1", - "-" + self.machine + ".special", "hq4x", - "-" + self.machine + ".videoip", "1"] - self.joy_ids = [] - self.find_joysticks() - if len(self.joy_ids) > 0: - self.set_joystick_controls() + options = ["-fs", fullscreen, + "-" + machine + ".xres", xres, + "-" + machine + ".yres", yres, + "-" + machine + ".stretch", "1", + "-" + machine + ".special", "hq4x", + "-" + machine + ".videoip", "1"] + joy_ids = self.find_joysticks() + if len(joy_ids) > 0: + controls = self.set_joystick_controls(joy_ids) + for control in controls: + options.append(control) else: logger.debug("No Joystick found") @@ -211,11 +216,11 @@ class mednafen(Runner): return {'error': 'RUNNER_NOT_INSTALLED', 'runner': self.__class__.__name__} - if not os.path.exists(self.rom): - return {'error': 'FILE_NOT_FOUND', 'file': self.rom} + if not os.path.exists(rom): + return {'error': 'FILE_NOT_FOUND', 'file': rom} command = [self.executable] - for option in self.options: + for option in options: command.append(option) - command.append("\"" + self.rom + "\"") + command.append("\"" + rom + "\"") return {'command': command} diff --git a/lutris/runners/mupen64plus.py b/lutris/runners/mupen64plus.py index 2260f001f..cf2371f27 100644 --- a/lutris/runners/mupen64plus.py +++ b/lutris/runners/mupen64plus.py @@ -19,13 +19,15 @@ ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################### +""" Runner for Nintendo64 """ + from lutris.runners.runner import Runner import os.path # pylint: disable=C0103 class mupen64plus(Runner): - '''Runner for Sega Genesis games''' + """Nintendo 64 emulator""" def __init__(self, settings=None): super(mupen64plus, self).__init__() @@ -33,9 +35,6 @@ class mupen64plus(Runner): self.executable = 'mupen64plus' self.machine = "Nintendo 64" self.arguments = ['--nogui'] - self.is_installable = True - self.description = "Nintendo 64 emulator" - self.game_options = [{ 'option': 'rom', 'type':'single', diff --git a/lutris/runners/nulldc.py b/lutris/runners/nulldc.py index b401258cc..5056c9da9 100644 --- a/lutris/runners/nulldc.py +++ b/lutris/runners/nulldc.py @@ -44,8 +44,6 @@ class nulldc(wine): def __init__(self, settings=None): """Initialize NullDC - TODO: Remove hardcoded stuff - joy2key $(xwininfo -root -tree | grep nullDC | grep -v VMU |\ awk '{print $1}') \ -X -rcfile ~/.joy2keyrc \ @@ -61,8 +59,6 @@ class nulldc(wine): config = LutrisConfig(runner=self.__class__.__name__) self.nulldc_path = config.get_path() self.executable = "nullDC_1.0.3_nommu.exe" - self.gamePath = "/mnt/seagate/games/Soul Calibur [NTSC-U]/" - self.gameIso = "disc.gdi" self.args = "" self.game_options = [{ 'option': 'iso', diff --git a/lutris/runners/o2em.py b/lutris/runners/o2em.py index 847bff4e0..1b88379c1 100644 --- a/lutris/runners/o2em.py +++ b/lutris/runners/o2em.py @@ -1,4 +1,3 @@ - # -*- coding:Utf-8 -*- ############################################################################### ## Lutris @@ -20,33 +19,73 @@ ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################### +""" Runner for Odyssey2 games """ + from lutris.runners.runner import Runner import os.path # pylint: disable=C0103 class o2em(Runner): - '''Runner for Odyssey² games''' + """Magnavox Oyssey² Emulator""" - def __init__(self,settings = None): + def __init__(self, settings=None): '''Constructor''' + super(o2em, self).__init__() self.package = "o2em" self.executable = "o2em" self.machine = "Odyssey 2" #o2em is not yet available as a package in Debian and Ubuntu, #it requires some packaging - self.is_installable = False - self.bios_path = os.path.join(os.path.expanduser("~"),".o2em/bios/") + self.bios_path = os.path.join(os.path.expanduser("~"), ".o2em/bios/") - self.description = "Magnavox Oyssey² Emulator" - bios_choices = [("Odyssey² bios","o2rom"),("French odyssey² Bios","c52"),("VP+ Bios","g7400"),("French VP+ Bios","jopac")] - controller_choices = [("Disable","0"),("Arrows keys and right shift","1"),("W,S,A,D,SPACE","2"),("Joystick","3")] - self.game_options = [{"option":"rom","type":"single","label":"Rom File"}] - self.runner_options = [{"option": "bios", "type":"one_choice", "choices":bios_choices,"label":"Bios"}, - {"option": "first_controller", "type":"one_choice","choices":controller_choices,"label":"First controller"}, - {"option": "second_controller", "type":"one_choice", "choices":controller_choices,"label":"Second controller"}, - {"option": "fullscreen", "type":"bool", "label":"Fullscreen"}, - {"option": "scanlines", "type":"bool", "label":"Scanlines"}] + bios_choices = [ + ("Odyssey² bios", "o2rom"), + ("French odyssey² Bios", "c52"), + ("VP+ Bios", "g7400"), + ("French VP+ Bios", "jopac") + ] + controller_choices = [ + ("Disable", "0"), + ("Arrows keys and right shift", "1"), + ("W,S,A,D,SPACE", "2"), + ("Joystick", "3") + ] + self.game_options = [{ + "option": "rom", + "type": "single", + "label": "Rom File" + }] + self.runner_options = [ + { + "option": "bios", + "type": "one_choice", + "choices":bios_choices, + "label":"Bios" + }, + { + "option": "first_controller", + "type": "one_choice", + "choices": controller_choices, + "label":"First controller" + }, + { + "option": "second_controller", + "type": "one_choice", + "choices": controller_choices, + "label": "Second controller" + }, + { + "option": "fullscreen", + "type": "bool", + "label": "Fullscreen" + }, + { + "option": "scanlines", + "type": "bool", + "label": "Scanlines" + } + ] self.arguments = ["-biosdir=\"%s\"" % self.bios_path] if settings: @@ -57,16 +96,16 @@ class o2em(Runner): if settings["o2em"]["scanlines"]: self.arguments = self.arguments + ["-scanlines"] if "first_controller" in settings["o2em"]: - self.arguments = self.arguments + ["-s1=%s" % settings["o2em"]["first_controller"]] + self.arguments += ["-s1=%s" % \ + settings["o2em"]["first_controller"]] if "second_controller" in settings["o2em"]: - self.arguments = self.arguments + ["-s2=%s" % settings["o2em"]["second_controller"]] + self.arguments += ["-s2=%s" % \ + settings["o2em"]["second_controller"]] romdir = os.path.dirname(settings["game"]["rom"]) romfile = os.path.basename(settings["game"]["rom"]) - self.arguments = self.arguments + ["-romdir=\"%s\"" % romdir+"/"] - self.arguments = self.arguments + ["\""+romfile+"\""] - + self.arguments = self.arguments + ["-romdir=\"%s\"/" % romdir] + self.arguments = self.arguments + ["\"%s\"" % romfile] def play(self): command = [self.executable] + self.arguments return command - diff --git a/lutris/runners/openmsx.py b/lutris/runners/openmsx.py index d05c25f8f..c9b01bf7b 100644 --- a/lutris/runners/openmsx.py +++ b/lutris/runners/openmsx.py @@ -19,6 +19,8 @@ ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################### +""" Runner for MSX games """ + from lutris.runners.runner import Runner @@ -27,6 +29,7 @@ class openmsx(Runner): '''Runner for MSX games''' def __init__(self, settings=None): '''Constructor''' + super(openmsx, self).__init__() self.package = "openmsx" self.executable = "openmsx" self.machine = "MSX" diff --git a/lutris/runners/osmose.py b/lutris/runners/osmose.py index 13d3de90c..d4e5a298f 100644 --- a/lutris/runners/osmose.py +++ b/lutris/runners/osmose.py @@ -19,24 +19,24 @@ ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################### +"""Runner for Sega Master System""" + +import os + from lutris.runners.runner import Runner # pylint: disable=C0103 class osmose(Runner): - '''Runner for Sega Master System games''' - + """Sega Master System Emulator""" def __init__(self, settings=None): '''Constructor''' + super(osmose, self).__init__() self.package = "osmose" self.executable = "osmose" self.machine = "Sega Master System" #osmose is not yet available as a package in Debian and Ubuntu, #it requires some packaging - self.is_installable = False - - self.description = "Sega Master System Emulator" - self.game_options = [{ 'option': 'rom', 'type': 'single', @@ -46,26 +46,24 @@ class osmose(Runner): {'option': 'fullscreen', 'type': 'bool', 'label': 'Fullscreen'}, {'option': 'joy', 'type': 'bool', 'label': 'Use joystick'} ] - self.arguments = [] - if settings: - self.settings = settings + self.settings = settings def play(self): + arguments = [] if 'fullscreen' in self.settings['osmose']: if self.settings['osmose']['fullscreen']: - self.arguments = self.arguments + ['-fs', '-bilinear'] + arguments = arguments + ['-fs', '-bilinear'] if 'joy' in self.settings["osmose"]: if self.settings['osmose']['joy']: - self.arguments = self.arguments + ['-joy'] + arguments = arguments + ['-joy'] - self.rom = self.settings['game']['rom'] - self.arguments = self.arguments + ["\"" + self.rom + "\""] + rom = self.settings['game']['rom'] + arguments = arguments + ["\"" + rom + "\""] if not self.is_installed(): return {'error': 'RUNNER_NOT_INSTALLED', 'runner': self.__class__.__name__} - if not os.path.exists(self.rom): + if not os.path.exists(rom): return {'error': 'FILE_NOT_FOUND', - 'file': self.rom} - - return {'command': [self.executable] + self.arguments} + 'file': rom} + return {'command': [self.executable] + arguments} diff --git a/lutris/runners/pcsx.py b/lutris/runners/pcsx.py index c0c87a23b..6425b1144 100644 --- a/lutris/runners/pcsx.py +++ b/lutris/runners/pcsx.py @@ -25,7 +25,7 @@ from lutris.runners.runner import Runner #pylint: disable=C0103 class pcsx(Runner): - """ Runner class for playstation games """ + """PlayStation emulator""" def __init__(self, settings=None): """ pcsx-df is what seems the best candidate for a playstation emulator. @@ -35,10 +35,9 @@ class pcsx(Runner): The package also lacks a maintainer : http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=510530 """ + super(pcsx, self).__init__() self.executable = "pcsx" self.package = "pcsx-df" - self.is_installable = False - self.description = "Runs PlayStation games" self.machine = "Playstation" self.game_options = [{"option":"iso", "type":"single", "label":"iso"}] self.runner_options = [] diff --git a/lutris/runners/runner.py b/lutris/runners/runner.py index caa98ceff..33c3ac690 100644 --- a/lutris/runners/runner.py +++ b/lutris/runners/runner.py @@ -19,18 +19,21 @@ ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################### +""" Generic runner """ + import subprocess import platform import hashlib -import logging from lutris.config import LutrisConfig from lutris.gui.common import ErrorDialog +from lutris.util.log import logger +# Pylint, are you from the past ? +# pylint: disable=R0921 class Runner(object): """Generic runner (base class for other runners) """ - def __init__(self): """ Initialize runner """ self.executable = None @@ -40,17 +43,29 @@ class Runner(object): self.game = None self.depends = None + @property + def description(self): + """Return the class' docstring as the description""" + return self.__doc__ + + # pylint: disable=E0102,E1101,W0201 + @description.setter + def description(self, value): + """Leave the ability to override the docstring""" + self.__doc__ = value + def load(self, game): """ Load a game """ self.game = game def play(self): - pass + """dummy method, must be implemented by derived runnners""" + raise NotImplementedError("Implement the play method in your runner") def check_depends(self): """Check if all the dependencies for a runner are installed.""" if not self.depends: - return true + return True classname = "lutris.runners." + self.depends parts = classname.split('.') @@ -80,13 +95,19 @@ class Runner(object): is_installed = True return is_installed + # pylint: disable=R0201 def get_game_options(self): - return None + """Not even sure that's used (well, let's see)""" + raise DeprecationWarning("WTF is this shit ?") + # pylint: disable=R0201 def get_runner_options(self): - return None + """Not even sure that's used (well, let's see)""" + raise DeprecationWarning("WTF is this shit ?") def get_game_path(self): + """Seems suspicious, but still useful""" + logger.warning("get_game_path called, I'm 12 and what is this ?") if hasattr(self, 'game_path'): path = self.game_path else: @@ -94,6 +115,8 @@ class Runner(object): return path def md5sum(self, filename): + """checks the md5sum of a file, does not belong here""" + logger.warning("please remove md5sum from Runner") md5check = hashlib.md5() file_ = open(filename, "rb") content = file_.readlines() @@ -122,19 +145,16 @@ class Runner(object): package_manager = 'yum' install_args = 'install' else: - logging.error("The distribution you're running is not supported.") - logging.error("Edit runners/runner.py to add support for it") + logger.error("The distribution you're running is not supported.") + logger.error("Edit runners/runner.py to add support for it") return False - stdout = subprocess.Popen("%s %s %s" % (package_manager, - install_args, - self.package), - shell=True, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE).communicate()[0] + subprocess.Popen("%s %s %s" % (package_manager, install_args, + self.package), + shell=True, stderr=subprocess.PIPE) return True - def write_config(self, id, name, fullpath): + def write_config(self, _id, name, fullpath): """Write game configuration to settings directory.""" system = self.__class__.__name__ index = fullpath.rindex("/") @@ -143,8 +163,12 @@ class Runner(object): if path.startswith("file://"): path = path[7:] config = LutrisConfig() - config.config = {"main": {"path": path, - "exe": exe, - "realname": name, - "runner": system}} - config.save(id, values) + config.config = { + "main": { + "path": path, + "exe": exe, + "realname": name, + "runner": system + } + } + config.save(config_type="game") diff --git a/lutris/runners/scummvm.py b/lutris/runners/scummvm.py index 9e8e3a40d..122d81259 100644 --- a/lutris/runners/scummvm.py +++ b/lutris/runners/scummvm.py @@ -18,7 +18,8 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################### -""" ScummVM runner """ + +""" Runner for point and click adventure games. """ import os import subprocess @@ -27,25 +28,52 @@ from lutris.runners.runner import Runner from lutris.config import LutrisConfig from ConfigParser import ConfigParser +SCUMMVM_CONFIG_FILE = os.path.join(os.path.expanduser("~"), ".scummvmrc") + + +def add_game(name, realname): + """Add scummvm from the auto-import""" + lutris_config = LutrisConfig() + lutris_config.config = {"runner": "scummvm", + "realname": realname, + "name": name} + lutris_config.save("game") + + +def import_games(): + """ + Parse the scummvm config file and imports + the games in Lutris config files. + """ + imported_games = [] + if os.path.exists(SCUMMVM_CONFIG_FILE): + config_parser = ConfigParser() + config_parser.read(SCUMMVM_CONFIG_FILE) + config_sections = config_parser.sections() + if "scummvm" in config_sections: + config_sections.remove("scummvm") + for section in config_sections: + realname = config_parser.get(section, "description") + add_game(section, realname) + imported_games.append({'id': section, + 'name': realname, + 'runner': 'scummvm'}) + return imported_games + # pylint: disable=C0103 class scummvm(Runner): - """ Runner for point and click adventure games. """ + """Runs LucasArts games based on the Scumm engine""" def __init__(self, settings=None): - self.scummvm_config_file = os.path.join(os.path.expanduser("~"), - ".scummvmrc") + super(scummvm, self).__init__() self.executable = "scummvm" self.package = "scummvm" - self.is_installable = True - self.description = "Runs LucasArts games based on the Scumm engine" self.machine = "LucasArts point and click games" - self.gfxmode = "--gfx-mode=normal" - self.fullscreen = "-f" # -F for windowed - self.installer_options = [{'option': 'foo', - 'type': "label", - 'label': "Click on install to launch" \ - + "ScummVM and install the game"}] - self.game_options = [] + self.installer_options = [{ + 'option': 'foo', + 'type': "label", + 'label': "Click on install to launch ScummVM and install the game" + }] scaler_modes = [ ("2x", "2x"), ("3x", "3x"), @@ -67,57 +95,35 @@ class scummvm(Runner): "type": "one_choice", "choices": scaler_modes} ] + self.settings = settings + def play(self): + settings = self.settings + gfxmode = "--gfx-mode=normal" + fullscreen = "-f" # -F for windowed if isinstance(settings, LutrisConfig): config = settings.config if "scummvm" in config: if "fullscreen" in config["scummvm"]: if config["scummvm"]["fullscreen"] == False: - self.fullscreen = "-F" + fullscreen = "-F" if "gfx-mode" in config["scummvm"]: mode = config["scummvm"]["gfx-mode"] - self.gfxmode = "--gfx-mode=%s" % mode - self.game = settings["name"] - - def play(self): - return [self.executable, self.fullscreen, self.gfxmode, self.game] - - def import_games(self): - """ - Parse the scummvm config file and imports - the games in Lutris config files. - """ - imported_games = [] - if os.path.exists(self.scummvm_config_file): - config_parser = ConfigParser() - config_parser.read(self.scummvm_config_file) - config_sections = config_parser.sections() - if "scummvm" in config_sections: - config_sections.remove("scummvm") - for section in config_sections: - realname = config_parser.get(section, "description") - self.add_game(section, realname) - imported_games.append({'id': section, - 'name': realname, - 'runner': 'scummvm'}) - - return imported_games + gfxmode = "--gfx-mode=%s" % mode + game = settings["name"] + return [self.executable, fullscreen, gfxmode, game] + # pylint: disable=R0201 def get_install_command(self): - command = "%s" % (self.executable) - return command - - def add_game(self, name, realname): - lutris_config = LutrisConfig() - lutris_config.config = {"runner": "scummvm", - "realname": realname, - "name": name} - lutris_config.save("game") + """WTF is this shit ?""" + raise DeprecationWarning + #command = "%s" % (self.executable) + #return command def get_game_list(self): """ Return the entire list of games supported by ScummVM """ scumm_output = subprocess.Popen( - [self.executable, "-z"], + ["scummvm", "-z"], stdout=subprocess.PIPE).communicate()[0] game_list = str.split(scumm_output, "\n") game_array = [] diff --git a/lutris/runners/sdlmame.py b/lutris/runners/sdlmame.py index b30646ead..f99960a66 100644 --- a/lutris/runners/sdlmame.py +++ b/lutris/runners/sdlmame.py @@ -28,46 +28,44 @@ from lutris.runners.runner import Runner # pylint: disable=C0103 class sdlmame(Runner): - """ Mame runner """ + """Runs arcade games with SDLMame""" def __init__(self, settings=None): """ Mame initialization """ super(sdlmame, self).__init__() self.executable = "mame" - self.package = "sdlmame" - self.description = "Runs arcade games with SDLMame" self.machine = "Arcade" - self.is_installable = False - self.fullscreen = True self.game_options = [{"option": "rom", "type":"single", "label":"Rom file"}] self.runner_options = [{"option":"windowed", "type":"bool", "label":"Windowed"}] - - if settings: - self.romdir = os.path.dirname(settings["game"]["rom"]) - self.rom = os.path.basename(settings["game"]["rom"]) - self.mameconfigdir = os.path.join(os.path.expanduser("~"), ".mame") - if "sdlmame" in settings.config: - if "windowed" in settings["sdlmame"]: - self.fullscreen = not settings["sdlmame"]["windowed"] + self.settings = settings def play(self): """ Launch the game. """ - if not os.path.exists(os.path.join(self.mameconfigdir, "mame.ini")): + settings = self.settings + fullscreen = True + if settings: + romdir = os.path.dirname(settings["game"]["rom"]) + rom = os.path.basename(settings["game"]["rom"]) + mameconfigdir = os.path.join(os.path.expanduser("~"), ".mame") + if "sdlmame" in settings.config: + if "windowed" in settings["sdlmame"]: + fullscreen = not settings["sdlmame"]["windowed"] + if not os.path.exists(os.path.join(mameconfigdir, "mame.ini")): try: - os.makedirs(self.mameconfigdir) + os.makedirs(mameconfigdir) except OSError: pass - os.chdir(self.mameconfigdir) + os.chdir(mameconfigdir) subprocess.Popen([self.executable, "-createconfig"], stdout=subprocess.PIPE) - os.chdir(self.romdir) - arguments = [] - if not self.fullscreen: - arguments = arguments + ["-window"] - return [self.executable, - "-inipath", self.mameconfigdir, - "-skip_gameinfo", - "-rompath", self.romdir, self.rom] + arguments + os.chdir(romdir) + arguments = [] + if not fullscreen: + arguments = arguments + ["-window"] + return [self.executable, + "-inipath", mameconfigdir, + "-skip_gameinfo", + "-rompath", romdir, rom] + arguments diff --git a/lutris/runners/snes9x.py b/lutris/runners/snes9x.py index 3439110fe..5a2502e21 100644 --- a/lutris/runners/snes9x.py +++ b/lutris/runners/snes9x.py @@ -26,7 +26,7 @@ from lutris.runners.runner import Runner # pylint: disable=C0103 class snes9x(Runner): - """ Uses snes9x to run SNES games """ + """Runs Super Nintendo games with Snes9x""" def __init__(self, settings=None): """It seems that the best snes emulator around it snes9x-gtk zsnes has no 64bit port @@ -34,7 +34,6 @@ class snes9x(Runner): super(snes9x, self).__init__() self.executable = "snes9x-gtk" self.package = None - self.description = "Runs Super Nintendo games with Snes9x" self.machine = "Super Nintendo" self.is_installable = True self.game_options = [{ diff --git a/lutris/runners/steam.py b/lutris/runners/steam.py index 34b477ba3..4396accd1 100644 --- a/lutris/runners/steam.py +++ b/lutris/runners/steam.py @@ -29,33 +29,45 @@ from lutris.runners.wine import wine from lutris.config import LutrisConfig +def get_name(steam_file): + """Get game name from some weird steam file""" + data = steam_file.read(1000) + if "name" in data: + index_of_name = str.find(data, "name") + index = index_of_name + 5 + char = "0" + name = "" + while ord(char) != 0x0: + char = data[index] + index = index + 1 + name = name + char + return name[:-1] + + +def get_appid_from_filename(filename): + """Get appid name from some weird steam file""" + if filename.endswith(".vdf"): + appid = filename[filename.find("_") + 1:filename.find(".")] + elif filename.endswith('.pkv'): + appid = filename[:filename.find("_")] + return appid + + # pylint: disable=C0103 class steam(wine): - """Runner for the Steam platform.""" + """Runs Steam games with Wine""" def __init__(self, settings=None): super(steam, self).__init__(settings) self.executable = "Steam.exe" - self.package = None - self.description = "Runs Steam games with Wine" self.machine = "Steam Platform" - #TODO : Put Steam Path in config file config = LutrisConfig(runner=self.__class__.__name__) self.game_path = config.get_path() - self.game_exe = "steam.exe" self.arguments = [] - self.depends = "wine" - self.is_installable = False - self.appid = "26800" self.game_options = [ {'option': 'appid', 'type': 'string', 'label': 'appid'}, {'option': 'args', 'type': 'string', 'label': 'arguments'} ] - if settings: - self.appid = settings['game']['appid'] - if 'args' in settings['game']: - self.args = settings['game']['args'] - else: - self.args = "" + self.settings = settings def install(self): dlg = QuestionDialog({ @@ -78,52 +90,33 @@ class steam(wine): if not self.check_depends(): return False if not self.game_path or \ - not os.path.exists(os.path.join(self.game_path, self.game_exe)): + not os.path.exists(os.path.join(self.game_path, self.executable)): return False else: return True - def get_name(self, steam_file): - data = steam_file.read(1000) - if "name" in data: - index_of_name = str.find(data, "name") - index = index_of_name + 5 - char = "0" - name = "" - while ord(char) != 0x0: - char = data[index] - index = index + 1 - name = name + char - return name[:-1] - - def get_appid_from_filename(self, filename): - if filename.endswith(".vdf"): - appid = filename[filename.find("_") + 1:filename.find(".")] - elif filename.endswith('.pkv'): - appid = filename[:filename.find("_")] - return appid - def get_appid_list(self): - self.game_list = [] + """Return the list of appids of all user's games""" + game_list = [] os.chdir(os.path.join(self.game_path, "appcache")) max_counter = 10010 files = [] counter = 0 - for file in os.listdir("."): + for filename in os.listdir("."): counter = counter + 1 if counter < max_counter: - files.append(file) + files.append(filename) else: break steam_apps = [] - for file in files: - if file.endswith(".vdf"): - test_file = open(file, "rb") - appid = self.get_appid_from_filename(file) - appname = self.get_name(test_file) + for filename in files: + if filename.endswith(".vdf"): + test_file = open(filename, "rb") + appid = get_appid_from_filename(filename) + appname = get_name(test_file) if appname: - steam_apps.append((appid, appname, file)) + steam_apps.append((appid, appname, filename)) test_file.close() steam_apps.sort() @@ -133,10 +126,18 @@ class steam(wine): 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])) + game_list.append((steam_app[0], steam_app[1])) steam_apps_file.close() + return game_list def play(self): + settings = self.settings + if settings: + appid = settings['game']['appid'] + if 'args' in settings['game']: + self.args = settings['game']['args'] + else: + self.args = "" if not self.check_depends(): return {'error': 'RUNNER_NOT_INSTALLED', 'runner': self.depends} @@ -145,10 +146,7 @@ class steam(wine): 'runner': self.__class__.__name__} 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) + steam_full_path = os.path.join(self.game_path, self.executable) command = ['wine', '"%s"' % steam_full_path, - '-applaunch', self.appid, self.args] + '-applaunch', appid, self.args] return {'command': command} diff --git a/lutris/runners/stella.py b/lutris/runners/stella.py index 11bc32c1f..60fc769fd 100644 --- a/lutris/runners/stella.py +++ b/lutris/runners/stella.py @@ -20,24 +20,30 @@ ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################### +'''Runner for stella Atari 2600 emulator''' + from lutris.runners.runner import Runner -class stella(Runner): - '''Runner for stella Atari 2600 emulator''' - def __init__(self,settings = None): +# pylint: disable=C0103 +class stella(Runner): + """Atari 2600 games emulator""" + + def __init__(self, settings=None): '''Constructor''' - super(stella,self).__init__() + super(stella, self).__init__() self.package = "stella" self.executable = "stella" self.machine = "Atari 2600" - self.description = "Run Atari 2600 games" - self.game_options = [{"option":"cart","type":"single","label":"Cartridge"}] + self.game_options = [{ + "option": "cart", + "type": "single", + "label":"Cartridge" + }] self.runner_options = [] if settings: self.cart = settings["game"]["cart"] - def play(self): - command = ['stella',"\""+self.cart+"\""] + command = ['stella', "\"%s\"" % self.cart] return {'command': command} diff --git a/lutris/runners/uae.py b/lutris/runners/uae.py index b2481fc97..482e8de0a 100644 --- a/lutris/runners/uae.py +++ b/lutris/runners/uae.py @@ -19,20 +19,21 @@ ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################### +""" Runs Amiga games with UAE""" + import os from lutris.runners.runner import Runner # pylint: disable=C0103 class uae(Runner): + """Runs Amiga games with UAE, yay""" def __init__(self, settings=None): super(uae, self).__init__() self.package = "uae" self.executable = "uae" - self.description = "Runs Amiga games with UAE" self.machine = "Amiga" self.uae_options = {} - self.is_installable = False control_choices = [("Mouse", "mouse"), ("Joystick 1", "joy0"), ("Joystick 2", "joy1"), ("Keyboard 1", "kbd1"), ("Keyboard 2", "kbd2"), ("Keyboard 3", "kbd3")] @@ -174,9 +175,6 @@ class uae(Runner): if inserted_disks == disks: break - def get_game_options(self): - return {"file": self.file_options, "options": self.runner_options} - def play(self): command = [self.executable] for option in self.uae_options: diff --git a/lutris/runners/vice.py b/lutris/runners/vice.py index 349390fd9..94c1e1efa 100644 --- a/lutris/runners/vice.py +++ b/lutris/runners/vice.py @@ -20,12 +20,14 @@ ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################### +'''Runner for MSX games''' + from lutris.runners.runner import Runner +# pylint: disable=C0103 class vice(Runner): - '''Runner for MSX games''' - + """Commodore Emulator""" def __init__(self, settings=None): '''Constructor''' super(vice, self).__init__() @@ -33,7 +35,6 @@ class vice(Runner): self.executable = "x64" self.machine = "Commodore 64" self.arguments = [] - self.description = "Commodore Emulator" self.game_options = [{ "option": "disk", "type": "single", diff --git a/lutris/runners/wine.py b/lutris/runners/wine.py index 538dbec2a..eeade34ef 100644 --- a/lutris/runners/wine.py +++ b/lutris/runners/wine.py @@ -16,28 +16,53 @@ # along with this program. If not, see . # +"""Wine runner""" + import os import subprocess import logging from os.path import exists -from lutris.runners.runner import Runner -from lutris.constants import TMP_PATH +from lutris.util.log import logger from lutris.settings import CACHE_DIR +from lutris.runners.runner import Runner +def set_regedit(path, key, value): + """Plays with the windows registry + + path is something like HKEY_CURRENT_USER\Software\Wine\Direct3D + """ + + logging.debug("Setting wine registry key : %s\\%s to %s", + path, key, value) + reg_path = os.path.join(CACHE_DIR, 'winekeys.reg') + #Make temporary reg file + reg_file = open(reg_path, "w") + reg_file.write("""REGEDIT4 + +[%s] +"%s"="%s" + +""" % (path, key, value)) + reg_file.close() + subprocess.call(["wine", "regedit", reg_path]) + os.remove(reg_path) + + +def kill(): + """The kill command runs wineserver -k""" + os.popen("winserver -k") + + +# pylint: disable=C0103 class wine(Runner): + '''Run Windows games with Wine''' def __init__(self, settings=None): + super(wine, self).__init__() self.executable = 'wine' - self.package = 'wine' self.machine = 'Windows games' - self.description = 'Run Windows games with Wine' - - self.prefix = None - - self.is_installable = True - self.installer_options = [{ 'option': 'installer', 'type': 'single', @@ -109,59 +134,20 @@ class wine(Runner): 'type': 'one_choice', 'choices': desktop_choices} ] - + self.settings = settings reg_prefix = "HKEY_CURRENT_USER\Software\Wine" self.reg_keys = { "RenderTargetLockMode": r"%s\Direct3D" % reg_prefix, "Audio": r"%s\Drivers" % reg_prefix, "MouseWarpOverride": r"%s\DirectInput" % reg_prefix, "Multisampling": r"%s\Direct3D" % reg_prefix, - "RenderTargetLockMode": r"%s\Direct3D" % reg_prefix, "OffscreenRenderingMode": r"%s\Direct3D" % reg_prefix, "DirectDrawRenderer": r"%s\Direct3D" % reg_prefix, "Version": r"%s" % reg_prefix, "Desktop": r"%s\Explorer" % reg_prefix } - if settings: - if 'exe' in settings['game']: - self.gameExe = settings['game']['exe'] - if 'args' in settings.config['game']: - self.args = settings['game']['args'] - else: - self.args = None - if self.__class__.__name__ in settings.config: - logging.debug('loading wine specific settings') - self.wine_config = settings.config[self.__class__.__name__] - else: - self.wine_config = None - - def set_regedit(self, path, key, value): - """Plays with the windows registry - - path is something like HKEY_CURRENT_USER\Software\Wine\Direct3D - """ - - logging.debug("Setting wine registry key : %s\\%s to %s" % - (path, key, value)) - reg_path = os.path.join(TMP_PATH, 'winekeys.reg') - #Make temporary reg file - reg_file = open(reg_path, "w") - reg_file.write("""REGEDIT4 - -[%s] -"%s"="%s" - -""" % (path, key, value)) - reg_file.close() - subprocess.call(["wine", "regedit", reg_path]) - os.remove(reg_path) - - def kill(self): - """The kill command runs wineserver -k""" - os.popen("winserver -k") - - def get_install_command(self, exe=None, iso=None): + def get_install_command(self, exe=None): """Return the installer command, either from an exe or an iso""" if exe: command = "%s %s" % (self.executable, exe) @@ -170,24 +156,35 @@ class wine(Runner): return False return command - def check_regedit_keys(self): + def check_regedit_keys(self, wine_config): + """Resets regedit keys according to config""" for key in self.reg_keys.keys(): - if key in self.wine_config: - self.set_regedit(self.reg_keys[key], key, - self.wine_config[key]) + if key in wine_config: + set_regedit(self.reg_keys[key], key, wine_config[key]) def play(self): - self.game_path = os.path.dirname(self.gameExe) - game_exe = os.path.basename(self.gameExe) - if not exists(self.game_path): - return {"error": "FILE_NOT_FOUND", "file": self.game_path} + settings = self.settings + if 'exe' in settings['game']: + game_exe = settings['game']['exe'] + if 'args' in settings.config['game']: + arguments = settings['game']['args'] + else: + arguments = None + if self.__class__.__name__ in settings.config: + logging.debug('loading wine specific settings') + wine_config = settings.config[self.__class__.__name__] + game_path = os.path.dirname(game_exe) + game_exe = os.path.basename(game_exe) + if not exists(game_path): + return {"error": "FILE_NOT_FOUND", "file": game_path} command = [] - if self.prefix and exists(self.prefix): - command.append("WINEPREFIX=%s ", self.prefix) + if "prefix" in wine_config and exists(wine_config['prefix']): + logger.debug("using WINEPREFIX %s", wine_config["prefix"]) + command.append("WINEPREFIX=%s ", wine_config['prefix']) command.append(self.executable) command.append("\"" + game_exe + "\"") - if self.args: - for arg in self.args.split(): + if arguments: + for arg in arguments.split(): command.append(arg) - self.check_regedit_keys() + self.check_regedit_keys(wine_config) return {'command': command} diff --git a/lutris/settings.py b/lutris/settings.py index f9c39521c..5c543473e 100644 --- a/lutris/settings.py +++ b/lutris/settings.py @@ -2,8 +2,30 @@ from os.path import join from xdg import BaseDirectory +PROJECT = "Lutris" +VERSION = "0.2.7" +WEBSITE = "http://lutris.net" +COPYRIGHT = "(c) 2010 Lutris Gaming Platform" +AUTHORS = ["Mathieu Comandon "] +ARTISTS = ["Ludovic Soulié "] + 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_DB = join(DATA_DIR, 'pga.db') + +LICENSE_TEXT = """ +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +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 . +""" diff --git a/lutris/shortcuts.py b/lutris/shortcuts.py index 0811d9477..89383e14e 100644 --- a/lutris/shortcuts.py +++ b/lutris/shortcuts.py @@ -7,7 +7,7 @@ from xdg import BaseDirectory from subprocess import Popen, PIPE from lutris.config import LutrisConfig -from lutris.settings import CACHE_DIR, DATA_DIR +from lutris.settings import CACHE_DIR, DATA_DIR def create_launcher(game, desktop=False, menu=False): diff --git a/lutris/thread.py b/lutris/thread.py index 721d31c3f..358482178 100644 --- a/lutris/thread.py +++ b/lutris/thread.py @@ -49,6 +49,7 @@ class LutrisThread(threading.Thread): self.killswitch = killswitch def attach_thread(self, thread): + """Attach child process that need to be killed on game exit""" self.child_processes.append(thread) def run(self): diff --git a/lutris/xdgmenu.py b/lutris/xdgmenu.py index f03761e9a..91522df34 100644 --- a/lutris/xdgmenu.py +++ b/lutris/xdgmenu.py @@ -1,8 +1,6 @@ +"""Surprise!""" import xdg -from xdg.Menu import xdg_config_dirs -from xdg.Menu import Menu - CACHE = xdg.Menu.parse("/etc/xdg/menus/applications.menu") print CACHE for entry in CACHE.getEntries():