From cc697348fce55560975dd8264531210b80d8f585 Mon Sep 17 00:00:00 2001 From: Mathieu Comandon Date: Mon, 27 Feb 2012 18:17:10 +0100 Subject: [PATCH] some pylint refactoring --- .bzrignore | 1 + lutris/config.py | 63 ++++++++++++++++++++++++------------------- lutris/gui/widgets.py | 56 ++++++++++++++++++++++++++------------ lutris/pga.py | 44 +++++++++++++++++------------- lutris/util/log.py | 21 ++++++++------- 5 files changed, 112 insertions(+), 73 deletions(-) diff --git a/.bzrignore b/.bzrignore index 9ba0b609f..59bafa945 100644 --- a/.bzrignore +++ b/.bzrignore @@ -3,5 +3,6 @@ build .project .pydevproject .settings +.ropeproject tags *.pyc diff --git a/lutris/config.py b/lutris/config.py index bb3c84c6f..db7c4fe87 100644 --- a/lutris/config.py +++ b/lutris/config.py @@ -15,14 +15,17 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # +"""Handle the basic configuration of Lutris.""" import os import yaml import logging 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 def check_config(): @@ -43,7 +46,6 @@ def check_config(): os.mkdir(config_path) if not os.path.isfile(PGA_PATH): - import lutris.pga as pga pga.create() @@ -69,13 +71,14 @@ class LutrisConfig(): #By default config type is system, it can also be runner and game #this means that when you call lutris_config_instance["key"] is will #pick up the right configuration depending of config_type - self.config_type = "system" if runner: self.runner = runner self.config_type = "runner" elif game: self.game = game self.config_type = "game" + else: + self.config_type = "system" #Read system configuration if os.path.exists(constants.system_config_full_path): @@ -87,31 +90,32 @@ class LutrisConfig(): file(constants.system_config_full_path, "w+") if self.game: - game_config_full_path = os.path.join(constants.GAME_CONFIG_PATH, - self.game + constants.CONFIG_EXTENSION) + game_config_full_path = join(GAME_CONFIG_PATH, + self.game + CONFIG_EXTENSION) if os.path.exists(game_config_full_path): try: content = file(game_config_full_path, 'r').read() self.game_config = yaml.load(content) self.runner = self.game_config["runner"] except yaml.scanner.ScannerError: - logging.debug("error parsing config file %s" % game_config_full_path) + logging.debug("error parsing config file %s", + game_config_full_path) except yaml.parser.ParserError: - logging.debug("error parsing config file %s" % game_config_full_path) + logging.debug("error parsing config file %s", + game_config_full_path) except KeyError: logging.debug("Runner key is mandatory !") if self.runner: - runner_config_full_path = os.path.join(constants.runner_config_path, - self.runner + constants.CONFIG_EXTENSION) + runner_config_full_path = join(constants.runner_config_path, + self.runner + CONFIG_EXTENSION) if os.path.exists(runner_config_full_path): - self.runner_config = yaml.load(file(runner_config_full_path, 'r').read()) + yaml_content = file(runner_config_full_path, 'r').read() + self.runner_config = yaml.load(yaml_content) self.update_global_config() def __getitem__(self, key): - """Allow to access config data directly by keys. - - """ + """Allow to access config data directly by keys.""" if self.config_type == "game": value = self.game_config[key] elif self.config_type == "runner": @@ -130,6 +134,7 @@ class LutrisConfig(): self.update_global_config() def update_global_config(self): + """Update the global config dict.""" for key in self.system_config.keys(): if key in self.config: self.config[key].update(self.system_config[key]) @@ -150,34 +155,35 @@ class LutrisConfig(): self.config[key] = self.game_config[key] def get_real_name(self): + """Return the real name of a game.""" + return self.config["realname"] def remove(self, game_name): - logging.debug("removing %s" % game_name) - os.remove(join(constants.GAME_CONFIG_PATH, - game_name + constants.CONFIG_EXTENSION)) + """Delete the configuration file from disk.""" + + logging.debug("removing %s", game_name) + os.remove(join(GAME_CONFIG_PATH, + game_name + CONFIG_EXTENSION)) def is_valid(self): - """Check the config data and return True if config is ok. + """Check the config data and return True if config is ok.""" - """ - try: - self.runner_name = self.game_config["runner"] - except KeyError: + if "runner" in self.game_config: + return True + else: print "Error in %s config file : No runner" % self.game return False - return True def save(self, runner_type=None): """Save configuration file The way to save config files can be set by the type argument or with self.config_type - """ self.update_global_config() - logging.debug("Saving config (type %s)" % runner_type) + logging.debug("Saving config (type %s)", runner_type) logging.debug(self.config) if runner_type is None: runner_type = self.config_type @@ -187,15 +193,16 @@ class LutrisConfig(): file(constants.system_config_full_path, "w").write(yaml_config) elif runner_type == "runner": runner_config_path = join(constants.runner_config_path, - self.runner + constants.CONFIG_EXTENSION) + self.runner + CONFIG_EXTENSION) file(runner_config_path, "w").write(yaml_config) elif runner_type == "game": if not self.game: self.game = self.config["runner"] \ + "-" + self.config["realname"].replace(" ", "_") - self.game_config_path = join(constants.GAME_CONFIG_PATH, - self.game.replace('/', '_') + constants.CONFIG_EXTENSION) - config_file = file(self.game_config_path, "w") + game_config_path = join(GAME_CONFIG_PATH, + self.game.replace('/', '_') + \ + CONFIG_EXTENSION) + config_file = file(game_config_path, "w") config_file.write(yaml_config) return self.game else: @@ -203,7 +210,7 @@ class LutrisConfig(): print "i don't know how to save this yet" def get_path(self, default=None): - """Get the path to install games for a given runner + """Get the path to install games for a given runner. Return False if it can't find an installation path """ diff --git a/lutris/gui/widgets.py b/lutris/gui/widgets.py index 0ef6d10ce..0d1090a8b 100644 --- a/lutris/gui/widgets.py +++ b/lutris/gui/widgets.py @@ -18,12 +18,14 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################### +"""Misc widgets used in the GUI.""" import os import gtk import gobject import pango import Image + from lutris.downloader import Downloader from lutris.constants import COVER_PATH, DATA_PATH import lutris.constants @@ -47,37 +49,46 @@ class GameTreeView(gtk.TreeView): model = gtk.ListStore(str, gtk.gdk.Pixbuf, str) model.set_sort_column_id(0, gtk.SORT_ASCENDING) self.set_model(model) - tp = gtk.CellRendererPixbuf() - column = gtk.TreeViewColumn("Runner", tp, pixbuf=self.COL_ICON) + image_cell = gtk.CellRendererPixbuf() + column = gtk.TreeViewColumn("Runner", image_cell, pixbuf=self.COL_ICON) self.append_column(column) - tr = gtk.CellRendererText() - tr.set_property("ellipsize", pango.ELLIPSIZE_END) - column = gtk.TreeViewColumn("Game", tr, markup=self.COL_TEXT) + text_cell = gtk.CellRendererText() + text_cell.set_property("ellipsize", pango.ELLIPSIZE_END) + column = gtk.TreeViewColumn("Game", text_cell, markup=self.COL_TEXT) self.append_column(column) - for game in sorted(games): - self.add_row(game) + if games: + for game in sorted(games): + self.add_row(game) def add_row(self, game): + """Add a game in the treeview.""" + model = self.get_model() - s = "%s \n%s" % (game['name'], game['runner']) + label = "%s \n%s" % \ + (game['name'], game['runner']) icon_path = os.path.join(lutris.constants.DATA_PATH, 'media/runner_icons', game['runner'] + '.png') pix = gtk.gdk.pixbuf_new_from_file_at_size(icon_path, ICON_SIZE, ICON_SIZE) - row = model.append([game['id'], pix, s, ]) + row = model.append([game['id'], pix, label, ]) return row def remove_row(self, model_iter): + """Remove a game from the treeview.""" + model = self.get_model() model.remove(model_iter) def sort_rows(self): + """Sort the game list.""" + model = self.get_model() gtk.TreeModelSort(model) class GameCover(gtk.Image): + """Widget displaing the selected game's cover""" def __init__(self, parent=None): super(GameCover, self).__init__() self.parent_window = parent @@ -85,14 +96,15 @@ class GameCover(gtk.Image): self.connect('drag_data_received', self.on_cover_drop) def set_game_cover(self, name): - coverFile = os.path.join(COVER_PATH, name + ".jpg") - if os.path.exists(coverFile): + """Change the cover currently displayed.""" + cover_file = os.path.join(COVER_PATH, name + ".jpg") + if os.path.exists(cover_file): #Resize the image - cover_pixbuf = gtk.gdk.pixbuf_new_from_file(coverFile) + cover_pixbuf = gtk.gdk.pixbuf_new_from_file(cover_file) dest_w = 250.0 - h = cover_pixbuf.get_height() - w = cover_pixbuf.get_width() - dest_h = h * (dest_w / w) + height = cover_pixbuf.get_height() + width = cover_pixbuf.get_width() + dest_h = height * (dest_w / width) self.set_from_pixbuf(cover_pixbuf.scale_simple( int(dest_w), int(dest_h), @@ -103,9 +115,11 @@ class GameCover(gtk.Image): self.set_from_file(os.path.join(DATA_PATH, "media/background.png")) def desactivate_drop(self): + """Deactivate DnD for the widget.""" self.drag_dest_unset() def activate_drop(self): + """Activate DnD for the widget.""" targets = [('text/plain', 0, 0), ('text/uri-list', 0, 0), ('text/html', 0, 0), @@ -115,6 +129,7 @@ class GameCover(gtk.Image): gtk.gdk.ACTION_COPY | gtk.gdk.ACTION_DEFAULT | gtk.gdk.ACTION_MOVE) def on_cover_drop(self, widget, context, x, y, selection, target, ts): + """Take action based on a drop on the widget.""" # TODO : Change mouse cursor if no game is selected # of course, it must not be handled here file_path = selection.data.strip() @@ -138,6 +153,7 @@ class GameCover(gtk.Image): class DownloadProgressBox(gtk.HBox): + """Progress bar used to monitor a file download.""" __gsignals__ = {'complete': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,)), @@ -147,6 +163,7 @@ class DownloadProgressBox(gtk.HBox): def __init__(self, params, cancelable=True): gtk.HBox.__init__(self, False, 2) + self.downloader = None self.progressbar = gtk.ProgressBar() self.progressbar.show() self.pack_start(self.progressbar, True) @@ -161,13 +178,16 @@ class DownloadProgressBox(gtk.HBox): self.dest = params['dest'] def start(self): + """Start downloading a file.""" print "starting to download %s" % self.url self.downloader = Downloader(self.url, self.dest) - self.timer_id = gobject.timeout_add(100, self.progress) + timer_id = gobject.timeout_add(100, self.progress) self.cancel_button.set_sensitive(True) self.downloader.start() + return timer_id def progress(self): + """Show download progress.""" progress = min(self.downloader.progress, 1) self.progressbar.set_fraction(progress) percent = progress * 100 @@ -179,10 +199,12 @@ class DownloadProgressBox(gtk.HBox): return False return True - def __stop_download(self, widget): + def __stop_download(self): + """Stop the current download.""" self.downloader.kill = True self.cancel_button.set_sensitive(False) def cancel(self): + """Cancel the current download.""" print "cancelling download" self.downloader.kill() diff --git a/lutris/pga.py b/lutris/pga.py index b45b28ef3..84e0911ac 100644 --- a/lutris/pga.py +++ b/lutris/pga.py @@ -15,8 +15,9 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # +"""Personnal Game Archive module. Handle local database of user's games.""" - +import unicodedata import sqlite3 import re @@ -24,48 +25,53 @@ from lutris.settings import PGA_PATH def slugify(value): - """ + """Remove special characters from a string and slugify it. + Normalizes string, converts to lowercase, removes non-alpha characters, and converts spaces to hyphens. """ - import unicodedata value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore') value = unicode(re.sub('[^\w\s-]', '', value).strip().lower()) return re.sub('[-\s]+', '-', value) def connect(): + """Connect to the local PGA database.""" return sqlite3.connect(PGA_PATH) def create(): - c = connect() - q = 'create table games (name text, slug text, machine text, runner text)' - c.execute(q) - c.commit() - c.close() + """Create the local PGA database.""" + con = connect() + query = 'create table games ' + \ + '(name text, slug text, machine text, runner text)' + con.execute(query) + con.commit() + con.close() def get_games(name_filter=None): - c = connect() - cur = c.cursor() + """Get the list of every game in database.""" + con = connect() + cur = con.cursor() if filter is not None: - q = "select * from where name LIKE = ?" - rows = cur.execute(q, (name_filter, )) + query = "select * from where name LIKE = ?" + rows = cur.execute(query, (name_filter, )) else: - q = "select * from games" - rows = cur.execute(q) + query = "select * from games" + rows = cur.execute(query) results = rows.fetchall() cur.close() - c.close() + con.close() return results def add_game(name, machine, runner): + """Adds a game to the PGA database.""" slug = slugify(name) - c = connect() - c.execute("""insert into games(name, slug, machine, runner) values + con = connect() + con.execute("""insert into games(name, slug, machine, runner) values (?, ?, ?, ?)""", (name, slug, machine, runner)) - c.commit() - c.close() + con.commit() + con.close() diff --git a/lutris/util/log.py b/lutris/util/log.py index fd5b25f79..8e0a6e36f 100644 --- a/lutris/util/log.py +++ b/lutris/util/log.py @@ -1,19 +1,22 @@ -from os.path import join, isdir, realpath -from os import makedirs +"""Utility module for creating an application wide logger.""" import logging import logging.handlers import xdg.BaseDirectory -cache_dir = realpath(join(xdg.BaseDirectory.xdg_cache_home, "lutris")) -if not isdir(cache_dir): - makedirs(cache_dir) +from os import makedirs +from os.path import join, isdir, realpath -LOG_FILENAME = join(cache_dir, "lutris.log") +CACHE_DIR = realpath(join(xdg.BaseDirectory.xdg_cache_home, "lutris")) +if not isdir(CACHE_DIR): + makedirs(CACHE_DIR) + +LOG_FILENAME = join(CACHE_DIR, "lutris.log") loghandler = logging.handlers.RotatingFileHandler(LOG_FILENAME, - maxBytes=20971520, backupCount=5) + maxBytes=20971520, + backupCount=5) logger = logging.getLogger('Lutris') -logformatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') +log_format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s' +logformatter = logging.Formatter(log_format) loghandler.setFormatter(logformatter) logger.setLevel(logging.INFO) logger.addHandler(loghandler) -