Files
vaiola/modelspace/ModelSpace.py

137 lines
4.5 KiB
Python

from pathlib import Path
import os
from modelspace.ModelPackage import ModelPackage
from modelspace.ModelPackageSelector import ModelPackageSelector
from modelspace.ModelSpaceDatabase import ModelSpaceDatabase
from modelspace.Repository import Repository
class ModelSpace:
def __init__(self, repo: Repository, path):
self.repo = repo
self.path = path
self.config_dir = Path(self.path) / '.vaiola'
os.makedirs(self.config_dir, exist_ok=True)
self._copier = self._hard_link_copier
self.db = ModelSpaceDatabase(str(self.config_dir))
self.selector = ModelPackageSelector(self.repo.model_sub_repo, set(self.installed_packages))
self.temp_installed_resources = self.installed_resources
def _reset_selector(self):
self.selector = ModelPackageSelector(self.repo.model_sub_repo, set(self.installed_packages))
self.temp_installed_resources = self.installed_resources
def check_for_file_conflicts(self, path: str | list[str]) -> list:
# TODO
raise NotImplemented
# conflicts = []
# if not isinstance(path, list): path = [path]
# for p in path:
# fullpath = Path(self.path) / p
# if fullpath.exists() or p in self.temp['pending_files'].index: conflicts.append(p)
# return conflicts
def get_dest_dir(self, package: ModelPackage):
# TODO
raise NotImplemented
def _register_package_in_temp(self, package: ModelPackage):
for resource in package.provides: self.temp_installed_resources.add(resource, package.uuid)
def _deptree(self, resource: str, answer = None, depth = 0) -> set[ModelPackage]:
selected_packages = set()
packages = self.selector.run(resource, answer)
deps = self.repo.model_sub_repo.deps_from_pkg_list(packages)
deps = deps - set(self.temp_installed_resources.keys)
for package in packages: self._register_package_in_temp(package)
for dep in deps:
selected_packages = selected_packages | self._deptree(dep, answer, depth + 1)
return selected_packages | packages
def install(self, resources: str | list[str], depth = 0, answer = None) -> None:
if depth == 0: self._reset_selector()
if isinstance(resources, str): resources = [resources]
selected_packages = set()
for resource in resources:
selected_packages = selected_packages | self._deptree(resource, answer)
# TODO check file conflicts
# TODO run copier
pass
@staticmethod
def _hard_link_copier(source_dir, dest_dir, file_paths):
"""Создает жесткие ссылки для файлов из источника в директорию назначения
Args:
source_dir (str): Путь к директории-источнику
dest_dir (str): Путь к директории-назначению
file_paths (list): Список относительных путей файлов в директории источника
"""
for file_path in file_paths:
# Формируем полный путь к исходному файлу
source_file = os.path.join(source_dir, file_path)
# Формируем полный путь к целевому файлу
dest_file = os.path.join(dest_dir, file_path)
# Создаем необходимые поддиректории в директории назначения
dest_dir_name = os.path.dirname(dest_file)
if dest_dir_name and not os.path.exists(dest_dir_name):
os.makedirs(dest_dir_name)
# Создаем жесткую ссылку
os.link(source_file, dest_file)
@property
def available_packages(self): return self.repo.model_sub_repo.packages
@property
def available_resources(self): return self.repo.model_sub_repo.resources
@property
def installed_manuals(self): return [m[0] if m and len(m) > 0 else None for m in self.db.get_all_manuals()] if self.db.get_all_manuals() else list()
@property
def installed_deps(self): return [m[0] if m and len(m) > 0 else None for m in self.db.get_all_deps()] if self.db.get_all_deps() else list()
@property
def installed_packages(self): return self.installed_manuals + self.installed_deps
@property
def installed_resources(self): return self.repo.model_sub_repo.resources_from_pkg_list(self.installed_packages)