from django.db.models import Model from epdb.logic import PackageManager from epdb.models import CompoundStructure, User, Package, Compound from uuid import UUID from .errors import EPAPINotFoundError, EPAPIPermissionDeniedError def get_compound_or_error(user, compound_uuid: UUID): """ Get compound by UUID with permission check. """ try: compound = Compound.objects.get(uuid=compound_uuid) package = compound.package except Compound.DoesNotExist: raise EPAPINotFoundError(f"Compound with UUID {compound_uuid} not found") # FIXME: optimize package manager to exclusively work with UUIDs if not user or user.is_anonymous or not PackageManager.readable(user, package): raise EPAPIPermissionDeniedError("Insufficient permissions to access this compound.") return compound def get_package_or_error(user, package_uuid: UUID): """ Get package by UUID with permission check. """ # FIXME: update package manager with custom exceptions to avoid manual checks here try: package = Package.objects.get(uuid=package_uuid) except Package.DoesNotExist: raise EPAPINotFoundError(f"Package with UUID {package_uuid} not found") # FIXME: optimize package manager to exclusively work with UUIDs if not user or user.is_anonymous or not PackageManager.readable(user, package): raise EPAPIPermissionDeniedError("Insufficient permissions to access this package.") return package def get_user_packages_qs(user: User | None): """Get all packages readable by the user.""" if not user or user.is_anonymous: return PackageManager.get_reviewed_packages() return PackageManager.get_all_readable_packages(user, include_reviewed=True) def get_user_entities_qs(model_class: Model, user: User | None): """Build queryset for reviewed package entities.""" if not user or user.is_anonymous: return model_class.objects.filter(package__reviewed=True).select_related("package") qs = model_class.objects.filter( package__in=PackageManager.get_all_readable_packages(user, include_reviewed=True) ).select_related("package") return qs def get_package_scoped_entities_qs( model_class: Model, package_uuid: UUID, user: User | None = None ): """Build queryset for specific package entities.""" package = get_package_or_error(user, package_uuid) qs = model_class.objects.filter(package=package).select_related("package") return qs def get_user_structures_qs(user: User | None): """Build queryset for structures accessible to the user (via compound->package).""" if not user or user.is_anonymous: return CompoundStructure.objects.filter(compound__package__reviewed=True).select_related( "compound__package" ) qs = CompoundStructure.objects.filter( compound__package__in=PackageManager.get_all_readable_packages(user, include_reviewed=True) ).select_related("compound__package") return qs def get_package_compound_scoped_structure_qs( package_uuid: UUID, compound_uuid: UUID, user: User | None = None ): """Build queryset for specific package compound structures.""" get_package_or_error(user, package_uuid) compound = get_compound_or_error(user, compound_uuid) qs = CompoundStructure.objects.filter(compound=compound).select_related("compound__package") return qs