diff --git a/mc-get.py b/mc-get.py index 168aa7c..dee62b8 100755 --- a/mc-get.py +++ b/mc-get.py @@ -23,7 +23,7 @@ def download_cache(url: str, filename: str, size: int, hash: str): api.download(url, size, cache_file_path) else: print(f"{filename} is in cache.") - if mcfs.check_file_hash(cache_file_path, hash): + if not mcfs.check_file_hash(cache_file_path, hash): os.remove(cache_file_path) raise HashError(f"Incorrect hash for {filename}") @@ -47,8 +47,18 @@ def install(projects: list, mc_ver, loader): not_found = [] unavailable = [] projects_ids = [] + already_installed = [] + + def get_mod_info_from_db(slug): + _db = mcgetdb.McGetDB(mcfs.mc_dir) + return _db.select_mod(slug) + _db.select_shader(slug) + _db.select_resourcepack(slug) + _db.select_modpack(slug) def check_project(slug): + if __name__ == "__main__": + mod_info = get_mod_info_from_db(slug) + if mod_info: + already_installed.append(mod_info[0]) + return id = api.check_project(project=slug) if id: projects_ids.append(id.id) @@ -107,6 +117,9 @@ def install(projects: list, mc_ver, loader): if unavailable: print("Cannot be installed:", *[project.title for project in unavailable], sep="\n\t") + if already_installed: + print("Already installed:", *[name + " " + version for _, name, _, version, _ in already_installed], sep="\n\t") + all_to_install = to_install + dependencies_to_install if not all_to_install: @@ -122,13 +135,15 @@ def install(projects: list, mc_ver, loader): for project, version in all_to_install: file = type("mc_file", (object,), version.files[0]) filename = file.filename + hash = file.hashes["sha512"] try: - download_cache(file.url, filename, file.size, file.hashes["sha512"]) + download_cache(file.url, filename, file.size, hash) except HashError: print(f"Failed to install {project.title} ({project.slug}) [{version.version_number}] due to an incorrect " f"hash") failed_to_install.append((project, version)) continue + match project.project_type: case "resourcepack": subdir = "resourcepacks" @@ -138,10 +153,27 @@ def install(projects: list, mc_ver, loader): subdir = "shaderpacks" case "modpack": modpack_install(filename) - continue + subdir = "modpacks" case _: raise NotImplementedError + if __name__ == "__main__": + db = mcgetdb.McGetDB(mcfs.mc_dir) + match project.project_type: + case "resourcepack": + db.add_resourcepack(slug=project.slug, proj_name=project.title, filename=filename, + version=version.version_number, hash=hash) + case "mod": + db.add_mod(slug=project.slug, proj_name=project.title, filename=filename, + version=version.version_number, hash=hash) + case "shader": + db.add_shader(slug=project.slug, proj_name=project.title, filename=filename, + version=version.version_number, hash=hash) + case "modpack": + db.add_modpack(slug=project.slug, proj_name=project.title, filename=filename, + version=version.version_number, hash=hash) + case _: + raise NotImplementedError mcfs.install(filename, subdir) if failed_to_install: print("Failed to install:", @@ -232,7 +264,7 @@ if __name__ == "__main__": parser_install = subparsers.add_parser("install", help="Install one or more mods or resources") parser_install.add_argument("projects", nargs="+") - parser_install.add_argument("--version", default=mc_ver) + parser_install.add_argument("--mc_ver", default=mc_ver) parser_install.add_argument("--loader", default=loader) parser_search = subparsers.add_parser("search", help="Find a mod or a resource") diff --git a/mcgetdb.py b/mcgetdb.py index 6d0bb38..7e195dc 100644 --- a/mcgetdb.py +++ b/mcgetdb.py @@ -3,6 +3,7 @@ import os DB_VERSION = 1 + class McGetDB: def __init_db(self): @@ -10,8 +11,34 @@ class McGetDB: db.execute(''' CREATE TABLE IF NOT EXISTS mods ( slug TEXT PRIMARY KEY NOT NULL, - install_path TEXT NOT NULL, - version TEXT NOT NULL + proj_name TEXT NOT NULL, + filename TEXT NOT NULL, + version TEXT NOT NULL, + hash TEXT NOT NULL + );''') + db.execute(''' + CREATE TABLE IF NOT EXISTS resourcepacks ( + slug TEXT PRIMARY KEY NOT NULL, + proj_name TEXT NOT NULL, + filename TEXT NOT NULL, + version TEXT NOT NULL, + hash TEXT NOT NULL + );''') + db.execute(''' + CREATE TABLE IF NOT EXISTS shaderpacks ( + slug TEXT PRIMARY KEY NOT NULL, + proj_name TEXT NOT NULL, + filename TEXT NOT NULL, + version TEXT NOT NULL, + hash TEXT NOT NULL + );''') + db.execute(''' + CREATE TABLE IF NOT EXISTS modpacks ( + slug TEXT PRIMARY KEY NOT NULL, + proj_name TEXT NOT NULL, + filename TEXT NOT NULL, + version TEXT NOT NULL, + hash TEXT NOT NULL );''') db.execute(''' CREATE TABLE IF NOT EXISTS properties ( @@ -26,6 +53,16 @@ class McGetDB: self.db = sqlite3.connect(self.db_path) self.__init_db() + self.add_mod = self.__db_insert("mods") + self.add_resourcepack = self.__db_insert("resourcepacks") + self.add_shader = self.__db_insert("shaderpacks") + self.add_modpack = self.__db_insert("modpacks") + + self.select_mod = self.__db_select_by_col("mods", "slug") + self.select_resourcepack = self.__db_select_by_col("resourcepacks", "slug") + self.select_shader = self.__db_select_by_col("shaderpacks", "slug") + self.select_modpack = self.__db_select_by_col("modpacks", "slug") + def get_properties(self): properties = None with self.db as db: @@ -34,7 +71,7 @@ class McGetDB: ''').fetchone() return properties - def set_properties(self, mc_ver, modloader = "NULL", dir_hierarhy = "default"): + def set_properties(self, mc_ver, modloader="NULL", dir_hierarhy="default"): with self.db as db: db.execute(''' DELETE FROM properties; @@ -43,8 +80,25 @@ class McGetDB: INSERT INTO properties VALUES (?, ?, ?, ?) ''', (DB_VERSION, mc_ver, modloader, dir_hierarhy)) - def add_mod(self): - pass + def __db_insert(self, table): + def insertion_func(**kargs): + keys = [] + values = [] + for key, value in kargs.items(): + keys.append(key) + values.append(value) + with self.db as db: + db.execute(f''' + INSERT INTO {table} ({', '.join([key for key in keys])}) VALUES ({', '.join(['?' for _ in values])}) + ''', values) + return insertion_func + + def __db_select_by_col(self, table, col): + def selection_func(col_value): + with self.db as db: + res = db.execute(f'SELECT * FROM {table} WHERE {col} = "{col_value}"') + return res.fetchall() + return selection_func def remove_mod(self): pass