async def setPriority(self, mod: ModelIndexType, priority: int) -> None: async with self.updateLock: mod = self[mod] mod.priority = priority if mod.target == 'mods': setSettingsValue(mod.filename, 'Priority', str(priority) if priority else '', self.configpath.joinpath('mods.settings')) await self.update(mod) self.setLastUpdateTime(datetime.now(tz=timezone.utc), False)
async def disable(self, mod: ModelIndexType) -> None: async with self.updateLock: mod = self[mod] oldstat = mod.enabled oldpath = self.getModPath(mod, True) undo = False renames = [] settings = 0 inputs = 0 try: mod.enabled = False if mod.target == 'mods': newpath = self.getModPath(mod) if oldpath != newpath: oldpath.rename(newpath) setSettingsValue(mod.filename, 'Enabled', '0', self.configpath.joinpath('mods.settings')) if mod.target == 'dlc': for file in oldpath.glob('**/*'): if file.is_file( ) and not file.name == '.w3mm' and not file.suffix == '.disabled': file = file.rename( file.with_suffix(file.suffix + '.disabled')) renames.append(file) settings = removeSettings( mod.settings, self.configpath.joinpath('user.settings')) inputs = removeSettings( mod.inputs, self.configpath.joinpath('input.settings')) await self.update(mod) except PermissionError: logger.bind(path=oldpath).exception( 'Could not disable mod, invalid permissions. Is it open in the explorer?' ) undo = True except Exception as e: logger.exception(f'Could not disable mod: {e}') undo = True if undo: newpath = self.getModPath(mod) mod.enabled = oldstat if newpath.is_dir() and newpath != oldpath: newpath.rename(oldpath) for rename in reversed(renames): rename.rename(rename.with_suffix('')) if settings: addSettings(mod.settings, self.configpath.joinpath('user.settings')) if inputs: addSettings(mod.inputs, self.configpath.joinpath('input.settings')) if mod.target == 'mods': setSettingsValue(mod.filename, 'Enabled', '1', self.configpath.joinpath('mods.settings')) # TODO: incomplete: handle xml and ini changes self.setLastUpdateTime(datetime.now(tz=timezone.utc))
async def add(self, mod: Mod) -> None: # TODO: incomplete: always override compilation trigger mod if self.modspath in [mod.source, *mod.source.parents]: raise InvalidSourcePath( mod.source, 'Invalid mod source: Mods cannot be installed from the mods directory' ) async with self.updateLock: if (mod.filename, mod.target) in self._modList: raise ModExistsError(mod.filename, mod.target) target = self.getModPath(mod) if target.exists(): # TODO: incomplete: make sure the mod is tracked by the model raise ModExistsError(mod.filename, mod.target) settings = 0 inputs = 0 try: target.mkdir(parents=True) # copy mod files for _file in mod.files: sourceFile = mod.source.joinpath(_file.source) targetFile = target.joinpath(_file.source) targetFile.parent.mkdir(parents=True, exist_ok=True) copyfile(sourceFile, targetFile) for _content in mod.contents: sourceFile = mod.source.joinpath(_content.source) targetFile = target.joinpath(_content.source) targetFile.parent.mkdir(parents=True, exist_ok=True) copyfile(sourceFile, targetFile) mod.installed = True settings = addSettings( mod.settings, self.configpath.joinpath('user.settings')) inputs = addSettings( mod.inputs, self.configpath.joinpath('input.settings')) setSettingsValue(mod.filename, 'Enabled', '1', self.configpath.joinpath('mods.settings')) await self.update(mod) except Exception as e: removeDirectory(target) if settings: removeSettings(mod.settings, self.configpath.joinpath('user.settings')) if inputs: removeSettings(mod.inputs, self.configpath.joinpath('input.settings')) removeSettingsSection( mod.filename, self.configpath.joinpath('mods.settings')) raise e self._modList[(mod.filename, mod.target)] = mod self.setLastUpdateTime(datetime.now(tz=timezone.utc))
async def add(self, mod: Mod) -> None: # TODO: incomplete: always override compilation trigger mod if self.modspath in [mod.source, *mod.source.parents]: raise InvalidSourcePath( mod.source, 'Invalid mod source: Mods cannot be installed from the mods directory' ) async with self.updateLock: if (mod.filename, mod.target) in self._modList: raise ModExistsError(mod.filename, mod.target) target = self.getModPath(mod) if target.exists(): # TODO: incomplete: make sure the mod is tracked by the model raise ModExistsError(mod.filename, mod.target) settings = 0 inputs = 0 try: event_loop = asyncio.get_running_loop() target.mkdir(parents=True) # copy mod files copies = [] logger.bind(name=mod.filename, path=target).debug('Copying binary files') for _file in mod.files: sourceFile = mod.source.joinpath(_file.source) targetFile = target.joinpath(_file.source) targetFile.parent.mkdir(parents=True, exist_ok=True) copies.append((sourceFile, targetFile)) await asyncio.gather(*[ event_loop.run_in_executor( None, partial(copyfile, _copy[0], _copy[1])) for _copy in copies ]) copies = [] logger.bind(name=mod.filename, path=target).debug('Copying content files') for _content in mod.contents: sourceFile = mod.source.joinpath(_content.source) targetFile = target.joinpath(_content.source) targetFile.parent.mkdir(parents=True, exist_ok=True) copies.append((sourceFile, targetFile)) await asyncio.gather(*[ event_loop.run_in_executor( None, partial(copyfile, _copy[0], _copy[1])) for _copy in copies ]) mod.installed = True # update settings logger.bind(name=mod.filename, path=target).debug('Updating settings') settings = addSettings( mod.settings, self.configpath.joinpath('user.settings')) inputs = addSettings( mod.inputs, self.configpath.joinpath('input.settings')) setSettingsValue(mod.filename, 'Enabled', '1', self.configpath.joinpath('mods.settings')) await self.update(mod) except Exception as e: removeDirectory(target) if settings: removeSettings(mod.settings, self.configpath.joinpath('user.settings')) if inputs: removeSettings(mod.inputs, self.configpath.joinpath('input.settings')) removeSettingsSection( mod.filename, self.configpath.joinpath('mods.settings')) raise e self._modList[(mod.filename, mod.target)] = mod self.updateBundledContentsConflicts() self.setLastUpdateTime(datetime.now(tz=timezone.utc))