def test_get_data(self): """ Check geode_gem.engine.utils.get_data method """ path = get_data("test", "test_engine_utils.py") self.assertTrue(path.exists()) path = get_data("setup.py") self.assertTrue(path.exists()) path = get_data("config", "not_exists.file") self.assertFalse(path.exists())
def test_get_creation_datetime(self): """ Check geode_gem.engine.utils.get_creation_datetime method """ creation_date = get_creation_datetime( get_data("test", "test_engine_utils.py")) self.assertIs(type(creation_date), datetime) creation_date = get_creation_datetime("not_exists.file") self.assertIsNone(creation_date)
def __init_database(self): """ Initialize database Check GEM database from local folder and update if needed columns and data """ try: config = Configuration(get_data("data", "config", GEM.Databases), strict=False) # Check GEM database file self.database = Database(self.__database_path, config, self.logger) # Check current GEM version version = self.database.select("gem", "version") # Check Database inner version and GEM version if not version == GEM.Version: if version is None: self.logger.info("Generate a new database") version = GEM.Version else: self.logger.info(f"Update database to v.{GEM.Version}") self.database.modify("gem", {"version": GEM.Version}, {"version": version}) else: self.logger.debug(f"Use GEM API v.{GEM.Version}") # Check integrity and migrate if necessary self.logger.info("Check database integrity") if not self.database.check_integrity(): self.logger.warning("Database need a migration") self.__need_migration = True else: self.logger.info("Current database is up-to-date") self.__need_migration = False except OSError as error: self.logger.exception(f"Cannot access to database: {error}") sys_exit(error) except ValueError as error: self.logger.exception(f"A wrong value occur: {error}") sys_exit(error) except Exception as error: self.logger.exception(f"An error occur: {error}") sys_exit(error)
def init_environment(): """ Initialize main environment """ # Initialize localization bindtextdomain("gem", str(get_data("data", "i18n"))) textdomain("gem") # Initialize metadata metadata = Configuration(get_data("data", "config", "metadata.conf")) # Retrieve metadata informations if metadata.has_section("metadata"): for key, value in metadata.items("metadata"): setattr(Metadata, key.upper(), value) # Retrieve icons informations if metadata.has_section("icons"): for key, value in metadata.items("icons"): setattr(Icons, key.upper(), value) setattr(Icons.Symbolic, key.upper(), f"{value}-symbolic") if metadata.has_section("icon-sizes"): for key, value in metadata.items("icon-sizes"): setattr(Icons.Size, key.upper(), value.split()) # Retrieve columns informations if metadata.has_section("misc"): setattr(Columns, "ORDER", metadata.get("misc", "columns_order", fallback=str())) if metadata.has_section("list"): for key, value in metadata.items("list"): setattr(Columns.List, key.upper(), int(value)) if metadata.has_section("grid"): for key, value in metadata.items("grid"): setattr(Columns.Grid, key.upper(), int(value))
def __init_logger(self): """ Initialize logger Create a logger object based on logging library """ if self.__log_path.exists(): copy(self.__log_path, str(self.__log_path) + ".old") # Define log path with a global variable logging.log_path = str(self.__log_path) # Generate logger from log.conf fileConfig(str(get_data("data", "config", GEM.Logger))) self.logger = logging.getLogger("gem") if not self.debug: self.logger.setLevel(logging.INFO)
def init_configuration(gem): """ Initialize user configuration Parameters ---------- gem : gem.engine.api.GEM GEM API instance """ move_collection = False # ---------------------------------------- # Configuration # ---------------------------------------- for filename in ("gem.conf", "consoles.conf", "emulators.conf"): path = gem.get_config(filename) if not path.exists(): gem.logger.debug(f"Copy default {path}") # Copy default configuration copy(get_data("data", "config", filename), path) # ---------------------------------------- # Local # ---------------------------------------- for folder in ("logs", "notes"): path = gem.get_local(folder) if not path.exists(): gem.logger.debug(f"Generate {path} folder") try: path.mkdir(mode=0o755, parents=True) except FileExistsError: gem.logger.error(f"Path {path} already exists") # ---------------------------------------- # Cache # ---------------------------------------- for name in ("consoles", "emulators", "games"): sizes = getattr(Icons.Size, name.upper(), list()) for size in sizes: path = Folders.CACHE.joinpath(name, f"{size}x{size}") if not path.exists(): gem.logger.debug(f"Generate {path}") try: path.mkdir(mode=0o755, parents=True) except FileExistsError: gem.logger.error(f"Path {path} already exists") # ---------------------------------------- # Icons # ---------------------------------------- icons_path = gem.get_local("icons") # Create icons storage folder if not icons_path.exists(): gem.logger.debug(f"Generate {icons_path}") try: icons_path.mkdir(mode=0o755, parents=True) except FileExistsError: gem.logger.error(f"Path {icons_path} already exists") finally: move_collection = True # Remove older icons collections folders (GEM < 1.0) else: for folder in ("consoles", "emulators"): path = icons_path.joinpath(folder) if path.exists(): if path.is_dir(): rmtree(path) elif path.is_symlink(): path.unlink() move_collection = True # Copy default icons if move_collection: gem.logger.debug("Generate consoles icons folder") for filename in get_data("data", "icons").glob("*.png"): if filename.is_file(): # Check the file mime-type to avoid non-image file mime = magic_from_file(filename, mime=True) if mime.startswith("image/"): new_path = icons_path.joinpath(filename.name) if not new_path.exists(): gem.logger.debug(f"Copy {new_path}") copy(filename, new_path)
def check_database(self, updater=None): """ Check database and migrate to lastest GEM version if needed Parameters ---------- updater : class, optionnal Class to call when database is modified """ if self.__need_migration: self.logger.info("Backup database") # Database backup copy(self.__database_path, self.__backup_path) # Remove previous database self.__database_path.unlink() # ---------------------------------------- # Initialize new database # ---------------------------------------- try: config = Configuration( get_data("data", "config", GEM.Databases)) previous_database = Database(self.__backup_path, config, self.logger) new_database = Database(self.__database_path, config, self.logger) new_database.insert("gem", {"version": GEM.Version}) # ---------------------------------------- # Migrate data from previous database # ---------------------------------------- self.logger.info("Start database migration") # ---------------------------------------- # Migrate game by game # ---------------------------------------- games = previous_database.select("games", ['*']) if games is not None: # Get current table columns old_columns_name = previous_database.get_columns("games") # Get new table columns new_columns_name = new_database.get_columns("games") if updater is not None: updater.init(len(games)) counter = int() for row in games: counter += 1 row_data = dict() for element in row: column = old_columns_name[row.index(element)] # Avoid to retrieve columns which are no more used if column in new_columns_name: row_data[column] = element new_database.insert("games", row_data) if updater is not None: updater.update(counter) # ---------------------------------------- # Remove backup # ---------------------------------------- self.logger.info("Migration complete") self.__need_migration = False del previous_database del self.database setattr(self, "database", new_database) except Exception as error: self.logger.exception( f"An error occurs during migration: {error}") self.logger.info("Restore database backup") copy(self.__backup_path, self.__database_path) # Remove backup self.get_local("save.gem.db").unlink() if updater is not None: updater.close()
def __init_widgets(self): """ Load widgets into main interface """ # ------------------------------------ # Main window # ------------------------------------ self.set_title(Metadata.NAME) self.set_modal(True) self.set_can_focus(True) self.set_resizable(False) self.set_keep_above(True) self.set_skip_taskbar_hint(True) self.set_type_hint(Gdk.WindowTypeHint.SPLASHSCREEN) self.set_position(Gtk.WindowPosition.CENTER) # ------------------------------------ # Grid # ------------------------------------ self.grid = Gtk.Box() # Properties self.grid.set_spacing(4) self.grid.set_border_width(16) self.grid.set_homogeneous(False) self.grid.set_orientation(Gtk.Orientation.VERTICAL) # ------------------------------------ # Logo # ------------------------------------ self.label_splash = Gtk.Label() self.image_splash = Gtk.Image() # Properties self.label_splash.set_line_wrap(True) self.label_splash.set_use_markup(True) self.label_splash.set_line_wrap_mode(Pango.WrapMode.WORD) self.label_splash.set_markup( "<span weight='bold' size='x-large'>%s - %s</span>\n<i>%s</i>" % ( Metadata.NAME, Metadata.VERSION, Metadata.CODE_NAME)) self.image_splash.set_from_file( str(get_data("data", "desktop", "gem.svg"))) self.image_splash.set_pixel_size(256) # ------------------------------------ # Progressbar # ------------------------------------ self.label_progress = Gtk.Label() self.progressbar = Gtk.ProgressBar() # Properties self.label_progress.set_text(_("Migrating entries from old database")) self.label_progress.set_line_wrap_mode(Pango.WrapMode.WORD) self.label_progress.set_line_wrap(True) self.progressbar.set_show_text(True)