def __init__(self, parent, path, game): """ Constructor Parameters ---------- parent : gem.interface.Interface Main interface to access public variables path : str Script path game : gem.api.Game Game object """ Thread.__init__(self) GObject.GObject.__init__(self) # ------------------------------------ # Initialize variables # ------------------------------------ self.parent = parent self.logger = parent.logger self.path = path self.game = game self.name = generate_identifier(game.name)
def get_emulator(self, emulator): """ Get a specific emulator Parameters ---------- emulator : str Emulator identifier or name Returns ------- Emulator or None Found emulator """ if emulator is not None and len(emulator) > 0: if emulator in self.__data["emulators"].keys(): return self.__data["emulators"].get(emulator, None) # Check if emulator use name instead of identifier identifier = generate_identifier(emulator) if identifier in self.__data["emulators"].keys(): return self.__data["emulators"].get(identifier, None) return None
def get_console(self, console): """ Get a specific console Parameters ---------- console : str Console identifier or name Returns ------- gem.engine.api.Console or None Found console Examples -------- >>> g = GEM() >>> g.init() >>> g.get_console("nintendo-nes") <gem.engine.api.Console object at 0x7f174a986b00> """ if console is not None and len(console) > 0: if console in self.__data["consoles"].keys(): return self.__data["consoles"].get(console, None) # Check if console use name instead of identifier identifier = generate_identifier(console) if identifier in self.__data["consoles"].keys(): return self.__data["consoles"].get(identifier, None) return None
def __init_keys(self, **kwargs): """ Initialize object attributes """ for key, key_type in self.attributes.items(): if key in kwargs.keys(): value = kwargs[key] elif key_type is Path: value = None else: value = key_type() setattr(self, key, value) if key_type is Path and type(value) is str: path = Path(value).expanduser() if len(value) == 0: path = None setattr(self, key, path) setattr(self, "id", generate_identifier(self.name))
def __init_attributes(self): """ Initialize object attributes """ for key, key_type in self.attributes.items(): if key_type is Emulator or key_type is Path: setattr(self, key, None) elif key_type is date and key == "installed": setattr(self, key, None) elif key_type is date: setattr(self, key, date(1, 1, 1)) elif key_type is bool: setattr(self, key, False) else: setattr(self, key, key_type()) setattr(self, "id", generate_identifier(self.__path)) setattr(self, "name", self.__path.stem) setattr(self, "installed", get_creation_datetime(self.__path).date()) self.environment.clear() if self.__parent is not None: environment = self.__parent.environment if self.id in environment.keys(): for option in environment.options(self.id): self.environment[option.upper()] = environment.get( self.id, option, fallback=str())
def test_generate_identifier_from_file(self): """ Check geode_gem.engine.utils.generate_identifier method """ path = Path(gettempdir(), "Best Game in, the (World).gnu") path.touch() self.assertTrue(path.exists()) self.assertEqual(f"best-game-in-the-world-gnu-{path.stat().st_ino}", generate_identifier(path)) path.unlink() path = Path("It's an unexistant_file!.obvious") self.assertFalse(path.exists()) self.assertEqual("it-s-an-unexistant-file-obvious", generate_identifier(path))
def __init_keys(self, **kwargs): """ Initialize object attributes """ for key, key_type in self.attributes.items(): if key in kwargs.keys(): value = kwargs[key] elif key_type is Emulator or key_type is Path: value = None elif key_type is bool: value = False else: value = key_type() setattr(self, key, value) if key_type is Path and type(value) is str: if "<local>" in value and hasattr(self.__parent, "get_local"): value = value.replace("<local>", str(self.__parent.get_local())) path = Path(value).expanduser() if len(value) == 0: path = None setattr(self, key, path) elif key_type is Emulator and type(value) is str: setattr(self, key, self.__parent.get_emulator(value)) elif key_type is bool: if value == "yes": setattr(self, key, True) elif value == "no": setattr(self, key, False) elif key_type is list and type(value) is str: setattr(self, key, key_type()) if len(value.strip()) > 0: value = list(set(value.strip().split(';'))) value.sort() setattr(self, key, value) if not self.name and self.path: setattr(self, "name", self.path.stem) setattr(self, "id", generate_identifier(self.name)) if not self.name: setattr(self, "name", self.id)
def test_generate_identifier_from_strings(self): """ Check geode_gem.engine.utils.generate_identifier method """ strings = [("Unexistant_File.ext", "unexistant-file-ext"), ("An other File .oops", "an-other-file-oops")] for string, result in strings: self.assertEqual(generate_identifier(string), result)
def save(self): """ Save modification """ self.section = self.entry_name.get_text().strip() if len(self.section) == 0: return None data = {"id": generate_identifier(self.section), "name": self.section} value = self.entry_binary.get_text().strip() if len(value) > 0: data["binary"] = Path(value).expanduser() value = self.entry_icon.get_text().strip() if len(value) > 0: data["icon"] = Path(value).expanduser() value = self.entry_configuration.get_text().strip() if len(value) > 0: data["configuration"] = Path(value).expanduser() value = self.entry_save.get_text().strip() if len(value) > 0: data["savestates"] = str(Path(value).expanduser()) value = self.entry_screenshots.get_text().strip() if len(value) > 0: data["screenshots"] = str(Path(value).expanduser()) value = self.entry_launch.get_text().strip() if len(value) > 0: data["default"] = value value = self.entry_windowed.get_text().strip() if len(value) > 0: data["windowed"] = value value = self.entry_fullscreen.get_text().strip() if len(value) > 0: data["fullscreen"] = value # Avanced view status status = self.config.getboolean("advanced", "emulator", fallback=False) if not self.check_advanced.get_active() == status: self.config.modify("advanced", "emulator", self.check_advanced.get_active()) self.config.update() return data
def save(self): """ Save modification """ self.section = self.entry_name.get_text().strip() if len(self.section) == 0: return None data = { "id": generate_identifier(self.section), "name": self.section } value = self.file_folder.get_filename() if value is not None and len(value) > 0: data["path"] = Path(value).expanduser() value = self.entry_icon.get_text().strip() if len(value) > 0: data["icon"] = Path(value).expanduser() value = self.entry_extensions.get_text().strip() if len(value) > 0: data["extensions"] = value.split() data["ignores"] = list() for row in self.model_ignores: element = self.model_ignores.get_value(row.iter, 0) if element is not None and len(element) > 0: data["ignores"].append(element) data["favorite"] = self.switch_favorite.get_active() data["recursive"] = self.switch_recursive.get_active() data["emulator"] = self.api.get_emulator( self.combo_emulators.get_active_id()) # Avanced view status status = self.config.getboolean("advanced", "console", fallback=False) if not self.check_advanced.get_active() == status: self.config.modify( "advanced", "console", self.check_advanced.get_active()) self.config.update() return data
def test_game_copy(self): """ Check geode_gem.engine.game.Game.copy method """ with self.assertRaises(FileNotFoundError): self.game.copy(Path(gettempdir(), "unexisting_game.txt")) path = Path(gettempdir(), "duplicate_game.txt") path.touch() game = self.game.copy(path) self.assertEqual(game.id, generate_identifier(path)) self.assertEqual(game.name, path.stem) path.unlink()
def setUp(self): """ Initialize each test with some data """ self.directory = TemporaryDirectory() self.files = list() for index in range(0, 5): filename = NamedTemporaryFile(suffix=f"_{index}.ext", dir=self.directory.name) filename.write(b"something to generate the file, yay") self.files.append(filename) self.console = Console(None, path=Path(self.directory.name), emulator=Emulator(binary="python3"), extensions=["ext", "nop"]) self.first_game = Path(self.files[0].name) self.first_game_id = generate_identifier(self.first_game)
def copy(self, filename): """ Copy game data into a new instance Parameters ---------- filename : pathlib.Path Game file path Returns ------- gem.engine.game.Game Game object """ game = Game(self.__parent, filename) for key in self.attributes.keys(): setattr(game, key, getattr(self, key, None)) game.id = generate_identifier(filename) game.name = filename.stem return game
def __on_entry_update(self, widget=None): """ Update dialog response sensitive status Parameters ---------- widget : Gtk.Widget, optional Object which receive signal """ self.error = False # ------------------------------------ # Console name # ------------------------------------ icon = None tooltip = None name = self.entry_name.get_text() if len(name) > 0: # Always check identifier to avoid NES != NeS name = generate_identifier(name) # Check if current console exists in database if name in self.consoles.keys(): if self.console is None: self.error = True # Avoid to use a name which already exists in database elif not self.console.id == name: self.error = True if self.error: icon = Icons.ERROR tooltip = _("This console already exists, please, " "choose another name") else: self.error = True self.entry_name.set_icon_from_icon_name( Gtk.EntryIconPosition.PRIMARY, icon) self.entry_name.set_tooltip_text(tooltip) # ------------------------------------ # Console roms folder # ------------------------------------ path = self.file_folder.get_filename() if path is None or not Path(path).expanduser().exists(): self.error = True # ------------------------------------ # Console roms extensions # ------------------------------------ extensions = self.entry_extensions.get_text().strip() if len(extensions) == 0: self.error = True # ------------------------------------ # Console emulator # ------------------------------------ if self.combo_emulators.get_active_id() is None: self.error = True # ------------------------------------ # Start dialog # ------------------------------------ self.set_response_sensitive(Gtk.ResponseType.APPLY, not self.error)
def __on_entry_update(self, widget): """ Check if a value is not already used Parameters ---------- widget : Gtk.Widget Object which receive signal """ self.error = False # ------------------------------------ # Emulator name # ------------------------------------ icon = None tooltip = None name = self.entry_name.get_text() if len(name) > 0: # Always check identifier to avoid NES != NeS name = generate_identifier(name) # Check if current emulator exists in database if name in self.emulators: if self.emulator is None: self.error = True # Avoid to use a name which already exists in database elif not self.emulator.id == name: self.error = True if self.error: icon = Icons.ERROR tooltip = _("This emulator already exist, please, " "choose another name") else: self.error = True self.entry_name.set_icon_from_icon_name(Gtk.EntryIconPosition.PRIMARY, icon) self.entry_name.set_tooltip_text(tooltip) # ------------------------------------ # Emulator binary # ------------------------------------ icon = None tooltip = None binary_path = self.entry_binary.get_text() # No binary available in entry if len(binary_path) == 0: self.error = True # Binary not exists in available $PATH variable elif len(get_binary_path(binary_path)) == 0: self.error = True icon = Icons.ERROR tooltip = _("This binary not exist, please, check the path") if widget == self.entry_binary: self.entry_binary.set_icon_from_icon_name( Gtk.EntryIconPosition.PRIMARY, icon) self.entry_binary.set_tooltip_text(tooltip) # ------------------------------------ # Manage error # ------------------------------------ self.set_response_sensitive(Gtk.ResponseType.APPLY, not self.error)
def get_data(self): """ Retrieve data to duplicate from user choices Returns ------- dict Data to duplicate """ # Retrieve specified name name = self.entry_name.get_text().strip() if len(name) > 0: name += self.game.extension # Generate file path filepath = self.game.path.parent.joinpath(name) filename = filepath.stem data = {"paths": list(), "filepath": filepath, "database": False} # ------------------------------------ # Game file # ------------------------------------ data["paths"].append((self.game.path, filepath)) # ------------------------------------ # Savestates # ------------------------------------ if self.switch_savestate.get_active(): for path in self.game.savestates: new_path = Path( str(path).replace(self.game.path.stem, filename)) data["paths"].append((path, new_path)) # ------------------------------------ # Screenshots # ------------------------------------ if self.switch_screenshot.get_active(): for path in self.game.screenshots: new_path = Path( str(path).replace(self.game.path.stem, filename)) data["paths"].append((path, new_path)) # ------------------------------------ # Notes # ------------------------------------ if self.switch_note.get_active(): path = self.api.get_local("notes", f"{self.game.id}.txt") if path.exists(): data["paths"].append( (path, self.parent.api.get_local( "notes", generate_identifier(filename) + ".txt"))) # ------------------------------------ # Memory type # ------------------------------------ if self.switch_memory.get_active(): path = self.parent.get_mednafen_memory_type(self.game) if path.exists(): data["paths"].append( (path, path.replace(self.game.path.stem, filename))) # ------------------------------------ # Database # ------------------------------------ if self.switch_database.get_active(): data["database"] = True return data return None