prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Lutris 0.4.5 doesn’t launch (AssertionError)
  I'm using Linux Mint 18.1 (my de is Mate if that's any help) and I received the update for Lutris 0.4.5. I tried to launch Lutris after that and nothing seemed to happen. I then tried to launch it from the terminal with the command "lutris" and saw the following:
  
  ```python
  Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/lutris/gui/application.py", line 152, in do_activate
  self.window = LutrisWindow(application=self)
  File "/usr/lib/python3/dist-packages/lutris/gui/lutriswindow.py", line 84, in init
  desktopapps.sync_with_lutris()
  File "/usr/lib/python3/dist-packages/lutris/util/desktopapps.py", line 87, in sync_with_lutris
  mark_as_installed(appid, 'linux', game_info)
  File "/usr/lib/python3/dist-packages/lutris/util/desktopapps.py", line 32, in mark_as_installed
  assert game_info[key]
  AssertionError
  ```
  
  I do hope you fix it, as I run quite a few dosbox/scummvm games, and a Wine game with it, so I kind of need it for gaming. Thanks for the understanding.
  P.S. I had also posted it on the forum, but overcame my reluctance to not creating many accounts online, as it's kind of important that this gets resolved.
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `lutris/util/desktopapps.py`
  Content:
  ```
  1 """Get games installed as desktop applications."""
  2 
  3 import os
  4 import shutil
  5 import shlex
  6 import subprocess
  7 import re
  8 
  9 from gi.repository import Gio
  10 from lutris import pga
  11 from lutris.util.log import logger
  12 from lutris.util.strings import slugify
  13 from lutris.config import make_game_config_id, LutrisConfig
  14 
  15 IGNORED_GAMES = (
  16     "lutris", "mame", "dosbox", "playonlinux", "org.gnome.Games", "retroarch",
  17     "steam", "steam-runtime", "steam-valve", "steam-native", "PlayOnLinux",
  18     "fs-uae-arcade", "PCSX2", "ppsspp", "qchdman", "qmc2-sdlmame", "qmc2-arcade",
  19     "sc-controller", "epsxe"
  20 )
  21 IGNORED_EXECUTABLES = (
  22     "lutris", "steam"
  23 )
  24 
  25 IGNORED_CATEGORIES = (
  26     "Emulator", "Development", "Utility"
  27 )
  28 
  29 
  30 def mark_as_installed(appid, runner_name, game_info):
  31     for key in ['name', 'slug']:
  32         assert game_info[key]
  33     logger.info("Setting %s as installed" % game_info['name'])
  34     config_id = (game_info.get('config_path') or make_game_config_id(game_info['slug']))
  35     game_id = pga.add_or_update(
  36         name=game_info['name'],
  37         runner=runner_name,
  38         slug=game_info['slug'],
  39         installed=1,
  40         configpath=config_id,
  41         installer_slug=game_info['installer_slug']
  42     )
  43 
  44     game_config = LutrisConfig(
  45         runner_slug=runner_name,
  46         game_config_id=config_id,
  47     )
  48     game_config.raw_game_config.update({'appid': appid, 'exe': game_info['exe'], 'args': game_info['args']})
  49     game_config.save()
  50     return game_id
  51 
  52 
  53 def mark_as_uninstalled(game_info):
  54     assert 'id' in game_info
  55     assert 'name' in game_info
  56     logger.info('Setting %s as uninstalled' % game_info['name'])
  57     game_id = pga.add_or_update(
  58         id=game_info['id'],
  59         runner='',
  60         installed=0
  61     )
  62     return game_id
  63 
  64 
  65 def sync_with_lutris():
  66     apps = get_games()
  67     desktop_games_in_lutris = pga.get_desktop_games()
  68     slugs_in_lutris = set([str(game['slug']) for game in desktop_games_in_lutris])
  69 
  70     seen_slugs = set()
  71     for app in apps:
  72         game_info = None
  73         name = app[0]
  74         slug = slugify(name)
  75         appid = app[1]
  76         seen_slugs.add(slug)
  77 
  78         if slug not in slugs_in_lutris:
  79             game_info = {
  80                 'name': name,
  81                 'slug': slug,
  82                 'config_path': slug + '-desktopapp',
  83                 'installer_slug': 'desktopapp',
  84                 'exe': app[2],
  85                 'args': app[3]
  86             }
  87             mark_as_installed(appid, 'linux', game_info)
  88 
  89     unavailable_slugs = slugs_in_lutris.difference(seen_slugs)
  90     for slug in unavailable_slugs:
  91         for game in desktop_games_in_lutris:
  92             if game['slug'] == slug:
  93                 mark_as_uninstalled(game)
  94 
  95 
  96 def get_games():
  97     """Return the list of games stored in the XDG menu."""
  98     game_list = []
  99 
  100     apps = Gio.AppInfo.get_all()
  101     for app in apps:
  102         if app.get_nodisplay() or app.get_is_hidden():
  103             continue
  104         appid = os.path.splitext(app.get_id())[0]
  105         exe = None
  106         args = []
  107 
  108         # must be in Game category
  109         categories = app.get_categories()
  110         if not categories:
  111             continue
  112         categories = filter(None, categories.lower().split(';'))
  113         if 'game' not in categories:
  114             continue
  115 
  116         # contains a blacklisted category
  117         ok = True
  118         for c in categories:
  119             if c in map(str.lower, IGNORED_CATEGORIES):
  120                 ok = False
  121         if not ok:
  122             continue
  123 
  124         # game is blacklisted
  125         if appid.lower() in map(str.lower, IGNORED_GAMES):
  126             continue
  127 
  128         # executable is blacklisted
  129         if app.get_executable().lower() in IGNORED_EXECUTABLES:
  130             continue
  131 
  132         cli = shlex.split(app.get_commandline())
  133         exe = cli[0]
  134         args = cli[1:]
  135         # remove %U etc. and change %% to % in arguments
  136         args = list(map(lambda arg: re.sub('%[^%]', '', arg).replace('%%', '%'), args))
  137 
  138         args = subprocess.list2cmdline(args)
  139 
  140         if not exe.startswith('/'):
  141             exe = shutil.which(exe)
  142         game_list.append((app.get_display_name(), appid, exe, args))
  143     return game_list
  144
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/lutris/util/desktopapps.py b/lutris/util/desktopapps.py
  --- a/lutris/util/desktopapps.py
  +++ b/lutris/util/desktopapps.py
  @@ -18,6 +18,7 @@
       "fs-uae-arcade", "PCSX2", "ppsspp", "qchdman", "qmc2-sdlmame", "qmc2-arcade",
       "sc-controller", "epsxe"
   )
  +
   IGNORED_EXECUTABLES = (
       "lutris", "steam"
   )
  @@ -41,12 +42,19 @@
           installer_slug=game_info['installer_slug']
       )
   
  -    game_config = LutrisConfig(
  +    config = LutrisConfig(
           runner_slug=runner_name,
           game_config_id=config_id,
       )
  -    game_config.raw_game_config.update({'appid': appid, 'exe': game_info['exe'], 'args': game_info['args']})
  -    game_config.save()
  +    config.raw_game_config.update({
  +        'appid': appid,
  +        'exe': game_info['exe'],
  +        'args': game_info['args']
  +    })
  +    config.raw_system_config.update({
  +        'disable_runtime': True
  +    })
  +    config.save()
       return game_id
   
   
  @@ -71,8 +79,23 @@
       for app in apps:
           game_info = None
           name = app[0]
  -        slug = slugify(name)
           appid = app[1]
  +        slug = slugify(name)
  +
  +        # if it fails to get slug from the name
  +        if not slug:
  +            slug = slugify(appid)
  +
  +        if not name or not slug or not appid:
  +            logger.error("Failed to load desktop game "
  +                         "\"" + str(name) + "\" "
  +                         "(app: " + str(appid) + ", slug: " + slug + ")")
  +            continue
  +        else:
  +            logger.debug("Found desktop game "
  +                         "\"" + str(name) + "\" "
  +                         "(app: " + str(appid) + ", slug: " + slug + ")")
  +
           seen_slugs.add(slug)
   
           if slug not in slugs_in_lutris:
  
verification_info: {"golden_diff": "diff --git a/lutris/util/desktopapps.py b/lutris/util/desktopapps.py\n--- a/lutris/util/desktopapps.py\n+++ b/lutris/util/desktopapps.py\n@@ -18,6 +18,7 @@\n     \"fs-uae-arcade\", \"PCSX2\", \"ppsspp\", \"qchdman\", \"qmc2-sdlmame\", \"qmc2-arcade\",\n     \"sc-controller\", \"epsxe\"\n )\n+\n IGNORED_EXECUTABLES = (\n     \"lutris\", \"steam\"\n )\n@@ -41,12 +42,19 @@\n         installer_slug=game_info['installer_slug']\n     )\n \n-    game_config = LutrisConfig(\n+    config = LutrisConfig(\n         runner_slug=runner_name,\n         game_config_id=config_id,\n     )\n-    game_config.raw_game_config.update({'appid': appid, 'exe': game_info['exe'], 'args': game_info['args']})\n-    game_config.save()\n+    config.raw_game_config.update({\n+        'appid': appid,\n+        'exe': game_info['exe'],\n+        'args': game_info['args']\n+    })\n+    config.raw_system_config.update({\n+        'disable_runtime': True\n+    })\n+    config.save()\n     return game_id\n \n \n@@ -71,8 +79,23 @@\n     for app in apps:\n         game_info = None\n         name = app[0]\n-        slug = slugify(name)\n         appid = app[1]\n+        slug = slugify(name)\n+\n+        # if it fails to get slug from the name\n+        if not slug:\n+            slug = slugify(appid)\n+\n+        if not name or not slug or not appid:\n+            logger.error(\"Failed to load desktop game \"\n+                         \"\\\"\" + str(name) + \"\\\" \"\n+                         \"(app: \" + str(appid) + \", slug: \" + slug + \")\")\n+            continue\n+        else:\n+            logger.debug(\"Found desktop game \"\n+                         \"\\\"\" + str(name) + \"\\\" \"\n+                         \"(app: \" + str(appid) + \", slug: \" + slug + \")\")\n+\n         seen_slugs.add(slug)\n \n         if slug not in slugs_in_lutris:\n", "issue": "Lutris 0.4.5 doesn\u2019t launch (AssertionError)\nI'm using Linux Mint 18.1 (my de is Mate if that's any help) and I received the update for Lutris 0.4.5. I tried to launch Lutris after that and nothing seemed to happen. I then tried to launch it from the terminal with the command \"lutris\" and saw the following:\r\n\r\n```python\r\nTraceback (most recent call last):\r\nFile \"/usr/lib/python3/dist-packages/lutris/gui/application.py\", line 152, in do_activate\r\nself.window = LutrisWindow(application=self)\r\nFile \"/usr/lib/python3/dist-packages/lutris/gui/lutriswindow.py\", line 84, in init\r\ndesktopapps.sync_with_lutris()\r\nFile \"/usr/lib/python3/dist-packages/lutris/util/desktopapps.py\", line 87, in sync_with_lutris\r\nmark_as_installed(appid, 'linux', game_info)\r\nFile \"/usr/lib/python3/dist-packages/lutris/util/desktopapps.py\", line 32, in mark_as_installed\r\nassert game_info[key]\r\nAssertionError\r\n```\r\n\r\nI do hope you fix it, as I run quite a few dosbox/scummvm games, and a Wine game with it, so I kind of need it for gaming. Thanks for the understanding.\r\nP.S. I had also posted it on the forum, but overcame my reluctance to not creating many accounts online, as it's kind of important that this gets resolved.\n", "before_files": [{"content": "\"\"\"Get games installed as desktop applications.\"\"\"\n\nimport os\nimport shutil\nimport shlex\nimport subprocess\nimport re\n\nfrom gi.repository import Gio\nfrom lutris import pga\nfrom lutris.util.log import logger\nfrom lutris.util.strings import slugify\nfrom lutris.config import make_game_config_id, LutrisConfig\n\nIGNORED_GAMES = (\n    \"lutris\", \"mame\", \"dosbox\", \"playonlinux\", \"org.gnome.Games\", \"retroarch\",\n    \"steam\", \"steam-runtime\", \"steam-valve\", \"steam-native\", \"PlayOnLinux\",\n    \"fs-uae-arcade\", \"PCSX2\", \"ppsspp\", \"qchdman\", \"qmc2-sdlmame\", \"qmc2-arcade\",\n    \"sc-controller\", \"epsxe\"\n)\nIGNORED_EXECUTABLES = (\n    \"lutris\", \"steam\"\n)\n\nIGNORED_CATEGORIES = (\n    \"Emulator\", \"Development\", \"Utility\"\n)\n\n\ndef mark_as_installed(appid, runner_name, game_info):\n    for key in ['name', 'slug']:\n        assert game_info[key]\n    logger.info(\"Setting %s as installed\" % game_info['name'])\n    config_id = (game_info.get('config_path') or make_game_config_id(game_info['slug']))\n    game_id = pga.add_or_update(\n        name=game_info['name'],\n        runner=runner_name,\n        slug=game_info['slug'],\n        installed=1,\n        configpath=config_id,\n        installer_slug=game_info['installer_slug']\n    )\n\n    game_config = LutrisConfig(\n        runner_slug=runner_name,\n        game_config_id=config_id,\n    )\n    game_config.raw_game_config.update({'appid': appid, 'exe': game_info['exe'], 'args': game_info['args']})\n    game_config.save()\n    return game_id\n\n\ndef mark_as_uninstalled(game_info):\n    assert 'id' in game_info\n    assert 'name' in game_info\n    logger.info('Setting %s as uninstalled' % game_info['name'])\n    game_id = pga.add_or_update(\n        id=game_info['id'],\n        runner='',\n        installed=0\n    )\n    return game_id\n\n\ndef sync_with_lutris():\n    apps = get_games()\n    desktop_games_in_lutris = pga.get_desktop_games()\n    slugs_in_lutris = set([str(game['slug']) for game in desktop_games_in_lutris])\n\n    seen_slugs = set()\n    for app in apps:\n        game_info = None\n        name = app[0]\n        slug = slugify(name)\n        appid = app[1]\n        seen_slugs.add(slug)\n\n        if slug not in slugs_in_lutris:\n            game_info = {\n                'name': name,\n                'slug': slug,\n                'config_path': slug + '-desktopapp',\n                'installer_slug': 'desktopapp',\n                'exe': app[2],\n                'args': app[3]\n            }\n            mark_as_installed(appid, 'linux', game_info)\n\n    unavailable_slugs = slugs_in_lutris.difference(seen_slugs)\n    for slug in unavailable_slugs:\n        for game in desktop_games_in_lutris:\n            if game['slug'] == slug:\n                mark_as_uninstalled(game)\n\n\ndef get_games():\n    \"\"\"Return the list of games stored in the XDG menu.\"\"\"\n    game_list = []\n\n    apps = Gio.AppInfo.get_all()\n    for app in apps:\n        if app.get_nodisplay() or app.get_is_hidden():\n            continue\n        appid = os.path.splitext(app.get_id())[0]\n        exe = None\n        args = []\n\n        # must be in Game category\n        categories = app.get_categories()\n        if not categories:\n            continue\n        categories = filter(None, categories.lower().split(';'))\n        if 'game' not in categories:\n            continue\n\n        # contains a blacklisted category\n        ok = True\n        for c in categories:\n            if c in map(str.lower, IGNORED_CATEGORIES):\n                ok = False\n        if not ok:\n            continue\n\n        # game is blacklisted\n        if appid.lower() in map(str.lower, IGNORED_GAMES):\n            continue\n\n        # executable is blacklisted\n        if app.get_executable().lower() in IGNORED_EXECUTABLES:\n            continue\n\n        cli = shlex.split(app.get_commandline())\n        exe = cli[0]\n        args = cli[1:]\n        # remove %U etc. and change %% to % in arguments\n        args = list(map(lambda arg: re.sub('%[^%]', '', arg).replace('%%', '%'), args))\n\n        args = subprocess.list2cmdline(args)\n\n        if not exe.startswith('/'):\n            exe = shutil.which(exe)\n        game_list.append((app.get_display_name(), appid, exe, args))\n    return game_list\n", "path": "lutris/util/desktopapps.py"}], "after_files": [{"content": "\"\"\"Get games installed as desktop applications.\"\"\"\n\nimport os\nimport shutil\nimport shlex\nimport subprocess\nimport re\n\nfrom gi.repository import Gio\nfrom lutris import pga\nfrom lutris.util.log import logger\nfrom lutris.util.strings import slugify\nfrom lutris.config import make_game_config_id, LutrisConfig\n\nIGNORED_GAMES = (\n    \"lutris\", \"mame\", \"dosbox\", \"playonlinux\", \"org.gnome.Games\", \"retroarch\",\n    \"steam\", \"steam-runtime\", \"steam-valve\", \"steam-native\", \"PlayOnLinux\",\n    \"fs-uae-arcade\", \"PCSX2\", \"ppsspp\", \"qchdman\", \"qmc2-sdlmame\", \"qmc2-arcade\",\n    \"sc-controller\", \"epsxe\"\n)\n\nIGNORED_EXECUTABLES = (\n    \"lutris\", \"steam\"\n)\n\nIGNORED_CATEGORIES = (\n    \"Emulator\", \"Development\", \"Utility\"\n)\n\n\ndef mark_as_installed(appid, runner_name, game_info):\n    for key in ['name', 'slug']:\n        assert game_info[key]\n    logger.info(\"Setting %s as installed\" % game_info['name'])\n    config_id = (game_info.get('config_path') or make_game_config_id(game_info['slug']))\n    game_id = pga.add_or_update(\n        name=game_info['name'],\n        runner=runner_name,\n        slug=game_info['slug'],\n        installed=1,\n        configpath=config_id,\n        installer_slug=game_info['installer_slug']\n    )\n\n    config = LutrisConfig(\n        runner_slug=runner_name,\n        game_config_id=config_id,\n    )\n    config.raw_game_config.update({\n        'appid': appid,\n        'exe': game_info['exe'],\n        'args': game_info['args']\n    })\n    config.raw_system_config.update({\n        'disable_runtime': True\n    })\n    config.save()\n    return game_id\n\n\ndef mark_as_uninstalled(game_info):\n    assert 'id' in game_info\n    assert 'name' in game_info\n    logger.info('Setting %s as uninstalled' % game_info['name'])\n    game_id = pga.add_or_update(\n        id=game_info['id'],\n        runner='',\n        installed=0\n    )\n    return game_id\n\n\ndef sync_with_lutris():\n    apps = get_games()\n    desktop_games_in_lutris = pga.get_desktop_games()\n    slugs_in_lutris = set([str(game['slug']) for game in desktop_games_in_lutris])\n\n    seen_slugs = set()\n    for app in apps:\n        game_info = None\n        name = app[0]\n        appid = app[1]\n        slug = slugify(name)\n\n        # if it fails to get slug from the name\n        if not slug:\n            slug = slugify(appid)\n\n        if not name or not slug or not appid:\n            logger.error(\"Failed to load desktop game \"\n                         \"\\\"\" + str(name) + \"\\\" \"\n                         \"(app: \" + str(appid) + \", slug: \" + slug + \")\")\n            continue\n        else:\n            logger.debug(\"Found desktop game \"\n                         \"\\\"\" + str(name) + \"\\\" \"\n                         \"(app: \" + str(appid) + \", slug: \" + slug + \")\")\n\n        seen_slugs.add(slug)\n\n        if slug not in slugs_in_lutris:\n            game_info = {\n                'name': name,\n                'slug': slug,\n                'config_path': slug + '-desktopapp',\n                'installer_slug': 'desktopapp',\n                'exe': app[2],\n                'args': app[3]\n            }\n            mark_as_installed(appid, 'linux', game_info)\n\n    unavailable_slugs = slugs_in_lutris.difference(seen_slugs)\n    for slug in unavailable_slugs:\n        for game in desktop_games_in_lutris:\n            if game['slug'] == slug:\n                mark_as_uninstalled(game)\n\n\ndef get_games():\n    \"\"\"Return the list of games stored in the XDG menu.\"\"\"\n    game_list = []\n\n    apps = Gio.AppInfo.get_all()\n    for app in apps:\n        if app.get_nodisplay() or app.get_is_hidden():\n            continue\n        appid = os.path.splitext(app.get_id())[0]\n        exe = None\n        args = []\n\n        # must be in Game category\n        categories = app.get_categories()\n        if not categories:\n            continue\n        categories = filter(None, categories.lower().split(';'))\n        if 'game' not in categories:\n            continue\n\n        # contains a blacklisted category\n        ok = True\n        for c in categories:\n            if c in map(str.lower, IGNORED_CATEGORIES):\n                ok = False\n        if not ok:\n            continue\n\n        # game is blacklisted\n        if appid.lower() in map(str.lower, IGNORED_GAMES):\n            continue\n\n        # executable is blacklisted\n        if app.get_executable().lower() in IGNORED_EXECUTABLES:\n            continue\n\n        cli = shlex.split(app.get_commandline())\n        exe = cli[0]\n        args = cli[1:]\n        # remove %U etc. and change %% to % in arguments\n        args = list(map(lambda arg: re.sub('%[^%]', '', arg).replace('%%', '%'), args))\n\n        args = subprocess.list2cmdline(args)\n\n        if not exe.startswith('/'):\n            exe = shutil.which(exe)\n        game_list.append((app.get_display_name(), appid, exe, args))\n    return game_list\n", "path": "lutris/util/desktopapps.py"}]}