def __download_file(self, download): self.prepare_location(download.save_location) download_max_attempts = 5 download_attempt = 0 result = False while download_attempt < download_max_attempts: try: start_point, download_mode = self.get_start_point_and_download_mode( download) result = self.download_operation(download, start_point, download_mode) break except ConnectionError as e: print(e) download_attempt += 1 # mark download as complete self.__mark_download_as_complete(download, result) # Successful downloads if result: if download.number == download.out_of_amount: finish_thread = threading.Thread(target=download.finish) finish_thread.start() if self.__queue.empty(): Config.unset("current_download") # Unsuccessful downloads and cancels else: self.__cancel = False download.cancel() self.__current_download = None os.remove(download.save_location)
def __download_update(self, game: Game = None) -> None: Config.set("current_download", game.id) GLib.idle_add(self.__update_to_state, game.state.UPDATE_QUEUED, game) download_info = self.api.get_download_info(game) # Start the download for all files game.downloads = [] download_path = game.update_path finish_func = self.__update for key, file_info in enumerate(download_info['files']): if key > 0: download_path = "{}-{}.bin".format(self.update_path, key) download = Download(url=self.api.get_real_download_link( file_info["downlink"]), save_location=download_path, finish_func=finish_func, finish_func_args=game, progress_func=self.set_progress, progress_func_args=game, cancel_func=self.__cancel_update, cancel_func_args=game, number=key + 1, out_of_amount=len(download_info['files'])) game.downloads.append(download) DownloadManager.download(game.downloads)
def __init__(self, parent): Gtk.Dialog.__init__(self, title=_("Preferences"), parent=parent, modal=True) self.parent = parent self.__set_language_list() self.button_file_chooser.set_filename(Config.get("install_dir")) self.switch_keep_installers.set_active(Config.get("keep_installers")) self.switch_stay_logged_in.set_active(Config.get("stay_logged_in")) self.switch_show_fps.set_active(Config.get("show_fps")) self.switch_show_windows_games.set_active(Config.get("show_windows_games")) self.switch_create_shortcuts.set_active(Config.get("create_shortcuts")) self.switch_install_dlcs.set_active(Config.get("install_dlcs")) self.switch_automatic_updates.set_active(Config.get("automatic_updates")) self.switch_do_not_show_backgrounds.set_active(Config.get("do_not_show_backgrounds")) self.switch_do_not_show_media_tab.set_active(Config.get("do_not_show_media_tab")) # Set tooltip for keep installers label installer_dir = os.path.join(self.button_file_chooser.get_filename(), "installer") self.label_keep_installers.set_tooltip_text( _("Keep installers after downloading a game.\nInstallers are stored in: {}").format(installer_dir) ) # Only allow showing Windows games if wine is available if not shutil.which("wine"): self.switch_show_windows_games.set_sensitive(False) self.switch_show_windows_games.set_tooltip_text( _("Install Wine to enable this feature") )
def __save_install_dir_choice(self) -> bool: choice = self.button_file_chooser.get_filename() old_dir = Config.get("install_dir") if choice == old_dir: return True if not os.path.exists(choice): try: os.makedirs(choice) except: return False else: write_test_file = os.path.join(choice, "write_test.txt") try: with open(write_test_file, "w") as file: file.write("test") file.close() os.remove(write_test_file) except: return False # Remove the old directory if it is empty try: os.rmdir(old_dir) except OSError: pass Config.set("install_dir", choice) return True
def test_unset(self, mock_isfile): mock_isfile.return_value = True config = JSON_DEFAULT_CONFIGURATION with patch("builtins.open", mock_open(read_data=config)): from goodoldgalaxy.config import Config Config.unset("lang") lang = Config.get("lang") exp = None obs = lang self.assertEqual(exp, obs)
def __init__(self, name: str, url: str = None, game_id: int = 0 ): self.name = name self.url = url self.id = game_id self.install_dir: str = None self.image_url: str = None self.icon_url: str = None self.sidebar_icon_url: str = None self.logo_url: str = None self.background_url: str = None self.platform: str = None self.supported_platforms: list[str] = [] self.type : str = "game" self.genre: str = None self.genres: list[str] = [] self.updates: int = 0 self.dlc_count: int = 0 self.dlcs = [] self.tags: str = [] self.release_date: str = None self.language: str = None self.supported_languages: list[str] = [] self.installed: int = 0 self.installed_version: str = None self.available_version: str = None self.state:Enum = self.state.INSTALLABLE self.cache_dir: str = os.path.join(CACHE_DIR, "game/{}".format(game_id)) if os.path.exists(self.cache_dir) == False: os.makedirs(self.cache_dir) self.is_gog_game: int = 0 self.sidebar_tile = None self.list_tile = None self.grid_tile = None self.safe_name = self.__clean_filename(self.name) self.dlc_status_list = ["not-installed", "installed", "updatable"] self.dlc_status_file_name = "goodoldgalaxy-dlc.json" self.dlc_status_file_path = "" # Set folder for download installer self.download_dir = os.path.join(CACHE_DIR, "download") self.download_path = os.path.join(self.download_dir, self.safe_name) # Set folder for update installer self.update_dir = os.path.join(CACHE_DIR, "update") self.update_path = os.path.join(self.update_dir, self.safe_name) # Set folder if user wants to keep installer (disabled by default) self.keep_dir = os.path.join(Config.get("install_dir"), "installer") self.keep_path = os.path.join(self.keep_dir, self.safe_name) if not os.path.exists(CACHE_DIR): os.makedirs(CACHE_DIR) # available downloads self.__downloads = []
def get_game_achievements(self, game: Game) -> List[Achievement]: request_url = "https://gameplay.gog.com/clients/" + str( game.id) + "/users/" + str(Config.get("user_id")) + "/achievements" game_dir = os.path.join(CACHE_DIR, "game/{}".format(game.id)) if os.path.exists(game_dir) == False: os.makedirs(game_dir) file_path = os.path.join(game_dir, "achievements.json") do_request = True if os.path.exists(file_path) == True and time.time( ) - os.path.getmtime(file_path) < 60 * 60 * 24: do_request = False if do_request == True: response = self.__request(request_url) with open(file_path, 'w') as outfile: json.dump(response, outfile) else: with open(file_path, 'r') as infile: response = json.load(infile) achievements = [] for item in response["items"]: try: achievement = Achievement(game, item["achievement_id"], item["achievement_key"]) achievement.visible = item["visible"] achievement.name = item["name"] achievement.description = item["description"] achievement.image_url_unlocked = item["image_url_unlocked"] achievement.image_url_locked = item["image_url_locked"] achievement.date_unlocked = item["date_unlocked"] achievements.append(achievement) except Exception as e: print(e) return achievements
def get_download_info(self, game: Game, operating_system="linux", dlc=False, dlc_installers="") -> tuple: if dlc: installers = dlc_installers else: response = self.get_info(game) installers = response["downloads"]["installers"] possible_downloads = [] for installer in installers: if installer["os"] == operating_system: possible_downloads.append(installer) if not possible_downloads: if operating_system == "linux": return self.get_download_info(game, "windows") else: raise NoDownloadLinkFound( "Error: {} with id {} couldn't be installed".format( game.name, game.id)) download_info = possible_downloads[0] for installer in possible_downloads: if installer['language'] == Config.get("lang"): download_info = installer break if installer['language'] == "en": download_info = installer # Return last entry in possible_downloads. This will either be English or the first language in the list # This is just a backup, if the preferred language has been found, this part won't execute return download_info
def change_view_mode(self, button): iconname = self.library_mode_button.get_image().get_icon_name( ).icon_name if (iconname == "view-list-symbolic"): Config.set("viewas", "list") self.library_mode = "list" self.library_mode_button.set_image(self.image_view_as_grid) self.library_mode_button.set_tooltip_text(_("View as Grid")) self.view_as_list() else: Config.set("viewas", "grid") self.library_mode = "grid" self.library_mode_button.set_image(self.image_view_as_list) self.library_mode_button.set_tooltip_text(_("View as List")) self.view_as_grid() self.sync_library()
def __init__(self, parent, library: Library, api: Api): Gtk.Viewport.__init__(self) self.parent = parent self.api = api self.library = library self.library_mode = "list" self.show_installed_only = None # Set library view mode if (Config.get("viewas") == "list"): self.library_mode = "list" self.library_mode_button.set_image(self.image_view_as_grid) self.library_mode_button.set_tooltip_text(_("View as Grid")) self.library_viewport.add(self.listbox) else: self.library_mode = "grid" self.library_mode_button.set_image(self.image_view_as_list) self.library_mode_button.set_tooltip_text(_("View as List")) self.library_viewport.add(self.flowbox) # load library in background current_os = platform.system() if current_os == "Linux": self.ck_os_linux.set_active(True) elif current_os == "Windows": self.ck_os_windows.set_active(True) elif current_os == "Darwin": self.ck_os_mac.set_active(True)
def __install(self, game: Game = None): GLib.idle_add(self.__update_to_state, game.state.INSTALLING, game) game.install_dir = game.get_install_dir() try: if os.path.exists(game.keep_path): install_game(game, game.keep_path, main_window=self) else: install_game(game, game.download_path, main_window=self) except (FileNotFoundError, BadZipFile): GLib.idle_add(self.__update_to_state, game.state.DOWNLOADABLE, game) return GLib.idle_add(self.__update_to_state, game.state.INSTALLED, game) GLib.idle_add(self.__reload_state, game) # make user to add the game to the side bar # check if DLCs should also be installed if game.type == "game" and Config.get("install_dlcs"): # first ensure we know about game dlcs self.library.update_dlcs_for_game(game) if len(game.dlcs) == 0: return # now grab DLCs that can be installed downloads = [] for dlc in game.dlcs: try: download_info = self.api.get_download_info( dlc, game.platform, True, dlc.get_installers()) except Exception: # could not find a valid target, ignore it continue # set dlc information now, otherwise this will break later dlc.platform = game.platform dlc.language = game.language # add download # Start the download for all files for key, file_info in enumerate(download_info['files']): if key > 0: download_path = "{}-{}.bin".format( dlc.download_path, key) else: download_path = dlc.download_path download = Download(url=self.api.get_real_download_link( file_info["downlink"]), title=dlc.name, associated_object=dlc, save_location=download_path, number=key + 1, file_size=download_info["total_size"], out_of_amount=len( download_info['files'])) download.register_finish_function(self.__dlc_finish_func, [game, dlc]) download.register_progress_function( self.set_progress, game) download.register_cancel_function(self.__cancel_download, game) downloads.append(download) DownloadManager.download(downloads)
def __set_avatar(self): user_dir = os.path.join(CACHE_DIR, "user/{}".format(Config.get("user_id"))) avatar = os.path.join(user_dir, "avatar_menu_user_av_small.jpg") if os.path.isfile(avatar) and os.path.exists(avatar): GLib.idle_add(self.user_photo.set_from_file, avatar) return True return False
def __request(self, url: str = None, params: dict = None) -> tuple: # Refresh the token if needed if self.active_token_expiration_time < time.time(): print("Refreshing token") refresh_token = Config.get("refresh_token") Config.set("refresh_token", self.__refresh_token(refresh_token)) # Make the request headers = { 'Authorization': "Bearer " + self.active_token, } response = SESSION.get(url, headers=headers, params=params) if self.debug: print("Request: {}".format(url)) print("Return code: {}".format(response.status_code)) print("Response body: {}".format(response.text)) print("") return response.json()
def __download_file(self, game: Game, operating_system=None) -> None: Config.set("current_download", game.id) GLib.idle_add(self.__update_to_state, game.state.QUEUED, game) current_os = platform.system() if current_os == "Linux": current_os = "linux" elif current_os == "Windows": current_os = "windows" elif current_os == "Darwin": current_os = "mac" # pick current os if none was passed if operating_system is None: operating_system = current_os if game.platform is None: game.platform = operating_system download_info = self.api.get_download_info( game, operating_system=operating_system) # Start the download for all files game.downloads = [] download_path = game.download_path finish_func = self.__install for key, file_info in enumerate(download_info['files']): if key > 0: download_path = "{}-{}.bin".format(self.download_path, key) download = Download(url=self.api.get_real_download_link( file_info["downlink"]), title=download_info["name"], associated_object=game, save_location=download_path, number=key + 1, file_size=download_info["total_size"], out_of_amount=len(download_info['files'])) download.register_finish_function(finish_func, game) download.register_progress_function(self.set_progress, game) download.register_cancel_function(self.__cancel_download, game) game.downloads.append(download) DownloadManager.download(game.downloads)
def get_user_info(self, finish_fn=None) -> str: username = Config.get("username") userid = Config.get("user_id") avatar = None if userid is not None: user_dir = os.path.join(CACHE_DIR, "user/{}".format(userid)) if os.path.exists(user_dir) == False: os.makedirs(user_dir) avatar = os.path.join(user_dir, "avatar_menu_user_av_small.jpg") if not (os.path.isfile(avatar) and os.path.exists(avatar)): avatar = None if (avatar is not None and finish_fn is not None): finish_fn() if not username or not avatar: url = "https://embed.gog.com/userData.json" response = self.__request(url) username = response["username"] userid = response["userId"] Config.set("user_id", userid) Config.set("username", username) user_dir = os.path.join(CACHE_DIR, "user/{}".format(userid)) if os.path.exists(user_dir) == False: os.makedirs(user_dir) avatar = os.path.join(user_dir, "avatar_menu_user_av_small.jpg") download = Download(response["avatar"] + "_menu_user_av_small.jpg", avatar) download.register_finish_function(finish_fn) DownloadManager.download_now(download) return username
def __get_installed_games(self) -> List[Game]: games = [] directories = os.listdir(Config.get("install_dir")) for directory in directories: full_path = os.path.join(Config.get("install_dir"), directory) # Only scan directories if not os.path.isdir(full_path): continue # Make sure the gameinfo file exists gameinfo = os.path.join(full_path, "gameinfo") if os.path.isfile(gameinfo): with open(gameinfo, 'r') as file: name = file.readline().strip() version = file.readline().strip() version_dev = file.readline().strip() language = file.readline().strip() game_id = file.readline().strip() if not game_id: game_id = 0 else: game_id = int(game_id) game = Game(name=name, game_id=game_id) game.set_installed("linux", full_path, version) game.set_installed_language(language) games.append(game) else: game_files = os.listdir(full_path) for file in game_files: if re.match(r'^goggame-[0-9]*\.info$', file): with open(os.path.join(full_path, file), 'r') as info_file: info = json.loads(info_file.read()) game = Game(name=info["name"], game_id=int(info["gameId"])) game.set_installed("windows", full_path) game.set_installed_language(info["language"]) for lang in info["languages"]: game.add_language(lang) games.append(game) return games
def __authenticate(self): url = None if Config.get("stay_logged_in"): token = Config.get("refresh_token") else: Config.unset("username") Config.unset("user_id") Config.unset("refresh_token") token = None # Make sure there is an internet connection if not self.api.can_connect(): return try: authenticated = self.api.authenticate(refresh_token=token, login_code=url) except Exception as ex: print("Could not authenticate with GOG. Cause: {}".format(ex)) return while not authenticated: login_url = self.api.get_login_url() redirect_url = self.api.get_redirect_url() login = Login(login_url=login_url, redirect_url=redirect_url, parent=self) response = login.run() login.hide() if response == Gtk.ResponseType.DELETE_EVENT: Gtk.main_quit() exit(0) if response == Gtk.ResponseType.NONE: result = login.get_result() authenticated = self.api.authenticate(refresh_token=token, login_code=result) Config.set("refresh_token", authenticated)
def set_fps_display(): error_message = "" # Enable FPS Counter for Nvidia or AMD (Mesa) users if Config.get("show_fps"): os.environ[ "__GL_SHOW_GRAPHICS_OSD"] = "1" # For Nvidia users + OpenGL/Vulkan games os.environ[ "GALLIUM_HUD"] = "simple,fps" # For AMDGPU users + OpenGL games os.environ[ "VK_INSTANCE_LAYERS"] = "VK_LAYER_MESA_overlay" # For AMDGPU users + Vulkan games else: os.environ["__GL_SHOW_GRAPHICS_OSD"] = "0" os.environ["GALLIUM_HUD"] = "" os.environ["VK_INSTANCE_LAYERS"] = "" return error_message
def __init__(self, name): Gtk.ApplicationWindow.__init__(self, title=name) self.api = Api() self.offline = False self.library = Library(self.api) self.games = [] self.library_view = LibraryView(self, library=self.library, api=self.api) self.details = None res = self.get_screen_resolution() # we got resolution if res[0] > 0 and res[0] <= 1368: self.set_default_size(1024, 700) # Set the icon icon = GdkPixbuf.Pixbuf.new_from_file(LOGO_IMAGE_PATH) self.set_default_icon_list([icon]) self.installed_search.connect("search-changed", self.filter_installed) self.selection_button.hide() # Show the window self.show_all() self.selection_button.hide() self.selection_label.set_text(_("Library")) if not os.path.exists(CACHE_DIR): os.makedirs(CACHE_DIR) # Create the thumbnails directory if not os.path.exists(THUMBNAIL_DIR): os.makedirs(THUMBNAIL_DIR) # Interact with the API self.__authenticate() self.user_photo.set_tooltip_text( self.api.get_user_info(self.__set_avatar)) self.sync_library() # Check what was the last view if Config.get("last_view") == "Game": print("last view as game..") else: self.__show_library() # Register self as a download manager listener DownloadManager.register_listener(self.__download_listener_func)
def __set_language_list(self) -> None: languages = Gtk.ListStore(str, str) for lang in SUPPORTED_DOWNLOAD_LANGUAGES: languages.append(lang) self.combobox_language.set_model(languages) self.combobox_language.set_entry_text_column(1) self.renderer_text = Gtk.CellRendererText() self.combobox_language.pack_start(self.renderer_text, False) self.combobox_language.add_attribute(self.renderer_text, "text", 1) # Set the active option current_lang = Config.get("lang") for key in range(len(languages)): if languages[key][:1][0] == current_lang: self.combobox_language.set_active(key) break
def logout(self, button): # Unset everything which is specific to this user Config.unset("username") Config.unset("user_id") Config.unset("refresh_token") self.hide() # Show the login screen self.__authenticate() self.user_photo.set_tooltip_text(self.api.get_user_info()) self.user_photo.set_from_icon_name("contact-new", 4) self.sync_library() self.show_all()
def __init__(self, parent, game: Game, api: Api): Gtk.Viewport.__init__(self) self.parent = parent self.api = api self.game = None # Set some defaults and adjust the rest in set_game # Set folder for download installer self.download_dir = os.path.join(CACHE_DIR, "download") # Set folder for update installer self.update_dir = os.path.join(CACHE_DIR, "update") # Set folder if user wants to keep installer (disabled by default) self.keep_dir = os.path.join(Config.get("install_dir"), "installer") # create cache directory if not existing if not os.path.exists(CACHE_DIR): os.makedirs(CACHE_DIR) # create game supported platforms icons pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale( ICON_LINUX_PATH if self.__is_light_theme() else ICON_LINUX_LIGHT_PATH, 20, 20, True) self.image_os_linux.set_from_pixbuf(pixbuf) pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale( ICON_WINDOWS_PATH if self.__is_light_theme() else ICON_WINDOWS_LIGHT_PATH, 20, 20, True) self.image_os_windows.set_from_pixbuf(pixbuf) pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale( ICON_MAC_PATH if self.__is_light_theme() else ICON_MAC_LIGHT_PATH, 20, 20, True) self.image_os_mac.set_from_pixbuf(pixbuf) # hide platform icons by default, show on game specific code self.image_os_linux.hide() self.image_os_windows.show() self.image_os_mac.show() # handle game specific stuff self.set_game(game)
def __save_language_choice(self) -> None: lang_choice = self.combobox_language.get_active_iter() if lang_choice is not None: model = self.combobox_language.get_model() lang, _ = model[lang_choice][:2] Config.set("lang", lang)
def save_pressed(self, button): self.__save_language_choice() Config.set("keep_installers", self.switch_keep_installers.get_active()) Config.set("stay_logged_in", self.switch_stay_logged_in.get_active()) Config.set("show_fps", self.switch_show_fps.get_active()) Config.set("create_shortcuts", self.switch_create_shortcuts.get_active()) Config.set("install_dlcs", self.switch_install_dlcs.get_active()) Config.set("automatic_updates", self.switch_automatic_updates.get_active()) Config.set("do_not_show_backgrounds",self.switch_do_not_show_backgrounds.get_active()) Config.set("do_not_show_media_tab",self.switch_do_not_show_media_tab.get_active()) if self.switch_show_windows_games.get_active() != Config.get("show_windows_games"): Config.set("show_windows_games", self.switch_show_windows_games.get_active()) self.parent.reset_library() # Only change the install_dir is it was actually changed if self.button_file_chooser.get_filename() != Config.get("install_dir"): if self.__save_install_dir_choice(): DownloadManager.cancel_all_downloads() self.parent.reset_library() else: dialog = Gtk.MessageDialog( parent=self, modal=True, destroy_with_parent=True, message_type=Gtk.MessageType.ERROR, buttons=Gtk.ButtonsType.OK, text=_("{} isn't a usable path").format(self.button_file_chooser.get_filename()) ) dialog.run() dialog.destroy() self.destroy()
def set_game(self, game: Game = None): """ Sets the game to display Parameters: ----------- game: Game -> Game instance to display """ # bail out if game was not set or we are doing the same game if game is None or self.game == game: return self.game = game self.progress_bar = None self.download = None self.current_state = self.game.state # Update paths for current game # Set folder for download installer self.download_path = os.path.join(self.download_dir, self.game.name) # Set folder for update installer self.update_path = os.path.join(self.update_dir, self.game.name) # Set folder if user wants to keep installer (disabled by default) self.keep_path = os.path.join(self.keep_dir, self.game.name) # reload game state self.reload_state() # Icon if update is available self.update_icon.hide() if self.game.installed == 1 and self.game.updates is not None and self.game.updates > 0: self.update_icon.show() # Hide the store icon if there is no game URL if not self.game.url: self.menu_button_store.hide() # Show platform icons that match supported platforms if ("linux" in game.supported_platforms): self.image_os_linux.show() if ("windows" in game.supported_platforms): self.image_os_windows.show() if ("mac" in game.supported_platforms): self.image_os_mac.show() # Handle game genres genres = "" idx = 0 glen = len(game.genres) for genre in game.genres: if len(genre.strip()) == 0: continue genres += genre if idx < glen - 1: genres += ", " idx += 1 if idx > 0: self.genres_label.show() self.genres_header.show() self.genres_label.set_text(genres) else: self.genres_label.hide() self.genres_header.hide() # Set game installed version if game.installed_version and game.installed_version is not None and game.installed_version != "": self.installed_version_label.show() self.installed_version_label.set_text(game.installed_version) else: self.installed_version_label.hide() # Handle game languages languages = "" idx = 0 glen = len(game.supported_languages) for language in game.supported_languages: languages += language if idx < glen - 1: languages += ", " idx += 1 if idx > 0: self.languages_header.show() self.languages_label.show() self.languages_label.set_text(languages) else: self.languages_header.hide() self.languages_label.hide() # Set game release date if game.release_date is not None and game.release_date != "": dt = None if isinstance(game.release_date, str): dt = datetime.datetime.strptime(game.release_date, '%Y-%m-%dT%H:%M:%S%z') elif isinstance(game.release_date, dict): dt = datetime.datetime.strptime(game.release_date["date"], '%Y-%m-%d %H:%M:%S.%f') if dt is not None: self.release_date_header.show() self.release_date_label.show() self.release_date_label.set_text(dt.strftime('%Y-%m-%d')) else: self.release_date_header.hide() self.release_date_label.hide() # grab game details from api self.response = self.api.get_info(game) # Game description if "description" in self.response: # note this is self.description_header.show() self.description_label.show() self.description_label.set_property("use-markup", True) #self.description_lead_label.set_text(self.response["description"]["lead"]) try: desc = self.__cleanup_html( self.response["description"]["full"]) self.description_label.set_markup(desc) except Exception as e: print(e) else: self.description_header.hide() self.description_label.hide() # changelog if "changelog" in self.response: try: text = self.__cleanup_html(self.response["changelog"]) self.changelog.get_buffer().set_text(text) # show the tab self.notebook.get_nth_page(1).show() except Exception as e: print(e) else: # hide the tab self.notebook.get_nth_page(1).hide() self.changelog.get_buffer().set_text("") # first remove existing media while len(self.media_flowbox.get_children()) > 0: child = self.media_flowbox.get_children()[0] self.media_flowbox.remove(child) # destroy child which is a gtk image to see if we can get back some memory child.destroy() # screenshots sidx = 0 # Only handle the media tab if requested if Config.get("do_not_show_media_tab") == False: if "screenshots" in self.response: for screenshot in self.response["screenshots"]: sidx += 1 image_id = screenshot["image_id"] template = screenshot["formatter_template_url"] image_url = template.replace("{formatter}", "ggvgt_2x").replace( ".png", ".jpg") self.__add_screenshot(image_id, image_url) # videos vidx = 0 if "videos" in self.response: for video in self.response["videos"]: thumbnail_url = video["thumbnail_url"] video_url = video["video_url"] self.__add_video(vidx, video_url, thumbnail_url) sidx += 1 if sidx == 0: self.media_bar.hide() self.media_flowbox.hide() else: self.media_bar.show() self.media_flowbox.show() # first remove any existing downloads if self.downloadstree is not None and self.downloadstree.get_model( ) is not None: # clear the store self.downloadstree.get_model().get_model().clear() # remove columns while len(self.downloadstree.get_columns()) > 0: self.downloadstree.remove_column( self.downloadstree.get_columns()[0]) if self.goodiestree is not None and self.goodiestree.get_model( ) is not None: # clear the store self.goodiestree.get_model().clear() # remove columns while len(self.goodiestree.get_columns()) > 0: self.goodiestree.remove_column( self.goodiestree.get_columns()[0]) # downloads didx = 0 gidx = 0 #GdkPixbuf.Pixbuf downloads_store = Gtk.ListStore(str, str, str, str, str, str, str, str, int, str, str) downloads_cols = [ _("Name"), _("OS"), _("Language"), _("Type"), _("Size"), _("Version"), _("State"), "Location", "Id", "File Size", "Operating System" ] goodies_store = Gtk.ListStore(str, str, str, str, str, str) goodies_cols = [ _("Name"), _("Category"), _("Type"), _("Size"), _("Count"), _("Location") ] self.downloads_languages = set() self.downloads_os = [] self.download_links = [] self.goodies_links = [] if "downloads" in self.response: downloads = self.response["downloads"] for dltype in downloads: is_goodies = True if dltype == "bonus_content" else False items = downloads[dltype] download_type = DL_TYPES[dltype] for item in items: if is_goodies: gidx += 1 links = self.__append_to_list_store_for_download( goodies_store, item, download_type, is_goodies) for link in links: self.goodies_links.append(link) else: didx += 1 state = "N/A" if self.game.installed == 1: if self.game.installed_version == item["version"]: state = _("Installed") else: state = _("Update Available") links = self.__append_to_list_store_for_download( downloads_store, item, download_type, state=state, product_id=self.game.id, file_size=item["total_size"]) for link in links: self.download_links.append(link) if "expanded_dlcs" in self.response: dlcs = self.response["expanded_dlcs"] for dlc in dlcs: downloads = dlc["downloads"] for dltype in downloads: is_goodies = True if dltype == "bonus_content" else False items = downloads[dltype] download_type = DL_TYPES[dltype] for item in items: if is_goodies: gidx += 1 links = self.__append_to_list_store_for_download( goodies_store, item, "DLC " + download_type, is_goodies) for link in links: self.goodies_links.append(link) else: didx += 1 state = self.game.get_dlc_status( item["name"], item["version"] ) if self.game.installed > 0 else "N/A" if state == "installed": state = _("Installed") elif state == "updatable": state = _("Update Available") elif state == "not-installed": state = _("Install") links = self.__append_to_list_store_for_download( downloads_store, item, "DLC " + download_type, state=state, product_id=dlc["id"], file_size=item["total_size"]) # add game to dlc list self.game.add_dlc_from_json(dlc) for link in links: self.download_links.append(link) if (didx > 0): self.downloads_filter = downloads_store.filter_new() self.downloads_filter.set_visible_func(self.__downloads_filter, data=None) self.downloadstree.set_model(self.downloads_filter) self.__create_tree_columns(self.downloadstree, downloads_cols) for lang in self.downloads_languages: ck = Gtk.CheckButton(lang) ck.set_active( lang == IETF_DOWNLOAD_LANGUAGES[Config.get("lang")]) ck.connect("toggled", self.downloads_filter_changed) self.languagebox.pack_start(ck, False, True, 10) self.languagebox.show_all() self.downloads_header_box.show_all() self.downloadstree.show_all() # re-filter downloads self.downloads_filter.refilter() else: self.languagebox.hide() self.downloads_header_box.hide() self.downloadstree.hide() if (gidx > 0): self.goodiestree.set_model(goodies_store) self.__create_tree_columns(self.goodiestree, goodies_cols, True) self.goodies_header.show() self.goodiestree.show_all() else: self.goodies_header.hide() self.goodiestree.hide() # handle achievements self.load_achievements() # load the background image self.__background_width = None if self.background_image is not None: self.background_image.clear() if Config.get("do_not_show_backgrounds") == False: self.background_image.show() self.__load_background_image() else: self.background_image.hide()
def __get_install_dir(self): if self.game.install_dir: return self.game.install_dir return os.path.join(Config.get("install_dir"), self.game.get_install_directory_name())
def install_game(game, installer, parent_window=None, main_window=None) -> None: if not os.path.exists(installer): GLib.idle_add(__show_installation_error, game, _("{} failed to download.").format(installer), parent_window, main_window) raise FileNotFoundError( "The installer {} does not exist".format(installer)) if game.platform == "linux": if not __verify_installer_integrity(installer): GLib.idle_add( __show_installation_error, game, _("{} was corrupted. Please download it again.").format( installer), parent_window, main_window) os.remove(installer) raise FileNotFoundError( "The installer {} was corrupted".format(installer)) # Make sure the install directory exists library_dir = Config.get("install_dir") if not os.path.exists(library_dir): os.makedirs(library_dir) # Make a temporary empty directory for extracting the installer extract_dir = os.path.join(CACHE_DIR, "extract") temp_dir = os.path.join(extract_dir, str(game.id)) if os.path.exists(extract_dir): shutil.rmtree(extract_dir, ignore_errors=True) os.makedirs(temp_dir, mode=0o755) # Extract the installer subprocess.call(["unzip", "-qq", installer, "-d", temp_dir]) if len(os.listdir(temp_dir)) == 0: GLib.idle_add(__show_installation_error, game, _("{} could not be unzipped.").format(installer), parent_window, main_window) raise CannotOpenZipContent( "{} could not be unzipped.".format(installer)) # Make sure the install directory exists library_dir = Config.get("install_dir") if not os.path.exists(library_dir): os.makedirs(library_dir, mode=0o755) # Copy the game files into the correct directory tmp_noarch_dir = os.path.join(temp_dir, "data/noarch") copytree(tmp_noarch_dir, game.install_dir) if game.type == "game" and Config.get("create_shortcuts") == True: create_shortcuts(game) # Remove the temporary directory shutil.rmtree(temp_dir, ignore_errors=True) elif game.platform == "windows": # Set the prefix for Windows games prefix_dir = os.path.join(game.install_dir, "prefix") if not os.path.exists(prefix_dir): os.makedirs(prefix_dir, mode=0o755) os.environ["WINEPREFIX"] = prefix_dir # It's possible to set install dir as argument before installation command = ["wine", installer, "/dir=" + game.install_dir] process = subprocess.Popen(command) process.wait() if process.returncode != 0: GLib.idle_add( __show_installation_error, game, _("The installation of {} failed. Please try again.").format( installer), main_window) return else: GLib.idle_add(__show_installation_error, game, _("{} platform not supported.").format(installer), parent_window, main_window) raise Exception("Platform not supported") thumbnail_small = os.path.join(THUMBNAIL_DIR, "{}_100.jpg".format(game.id)) thumbnail_medium = os.path.join(THUMBNAIL_DIR, "{}_196.jpg".format(game.id)) if os.path.exists(thumbnail_small): shutil.copyfile(thumbnail_small, os.path.join(game.install_dir, "thumbnail_100.jpg")) if os.path.exists(thumbnail_medium): shutil.copyfile(thumbnail_medium, os.path.join(game.install_dir, "thumbnail_196.jpg")) if Config.get("keep_installers"): keep_dir = os.path.join(Config.get("install_dir"), "installer") download_dir = os.path.join(CACHE_DIR, "download") update_dir = os.path.join(CACHE_DIR, "update") if not os.path.exists(keep_dir): os.makedirs(keep_dir, mode=0o755) try: # It's needed for multiple files for file in os.listdir(download_dir): shutil.move(download_dir + '/' + file, keep_dir + '/' + file) except Exception as ex: print("Encountered error while copying {} to {}. Got error: {}". format(installer, keep_dir, ex)) try: # It's needed for multiple files for file in os.listdir(update_dir): shutil.move(update_dir + '/' + file, keep_dir + '/' + file) except Exception as ex: print("Encountered error while copying {} to {}. Got error: {}". format(installer, keep_dir, ex)) else: os.remove(installer) # finish up game.istalled = 1 game.updates = 0
def uninstall_game(game): if Config.get("create_shortcuts") == True: remove_shortcuts(game) shutil.rmtree(game.install_dir, ignore_errors=True) game.install_dir = None game.installed_version = None
def resume_download_if_expected(self): download_id = Config.get("current_download") all_games = self.library.get_games() for game in all_games: if download_id and download_id == game.id and game.state != game.state.INSTALLED: self.download_game(game)
def prevent_resume_on_startup(self, game): download_id = Config.get("current_download") if download_id and download_id == game.id: Config.unset("current_download")