Loading trapper/trapper-project/trapper/apps/accounts/admin.py +0 −1 Original line number Diff line number Diff line Loading @@ -504,7 +504,6 @@ class UserHttpUploaderAccountFilesAdmin(admin.ModelAdmin): list_filter = ("file_type", "uploaded_at", "account") search_fields = ("file_name", "account__user__username", "account__user__email") readonly_fields = ( "file", "file_size", "uploaded_at", "download_link", Loading trapper/trapper-project/trapper/apps/geomap/views/views_rest.py +6 −2 Original line number Diff line number Diff line Loading @@ -196,7 +196,9 @@ class CSDeploymentView( def get_object(self): qs = self.get_deployments(self.get_classification_project(), self.request.user) return get_object_or_404(qs, pk=self.kwargs["deployment_pk"]) deployment_pk = self.kwargs["deployment_pk"] qs = qs.filter(pk=deployment_pk).distinct() return get_object_or_404(qs) @transaction.atomic def destroy(self, request, *args, **kwargs): Loading Loading @@ -256,4 +258,6 @@ class CSDeploymentUpdateTimestampsView( def get_object(self): qs = self.get_deployments(self.get_classification_project(), self.request.user) return get_object_or_404(qs, pk=self.kwargs["deployment_pk"]) deployment_pk = self.kwargs["deployment_pk"] qs = qs.filter(pk=deployment_pk).distinct() return get_object_or_404(qs) trapper/trapper-project/trapper/apps/media_classification/admin.py +1 −11 Original line number Diff line number Diff line Loading @@ -151,18 +151,8 @@ class ProjectRoleInline(admin.TabularInline): raw_id_fields = ["user"] class ProjectCollectionInline(admin.TabularInline): model = ClassificationProjectCollection extra = 0 raw_id_fields = ("collection",) readonly_fields = ( "resources_count", "collection_storage", ) class ClassificationProjectAdmin(admin.ModelAdmin): inlines = [ProjectRoleInline, ProjectCollectionInline] inlines = [ProjectRoleInline] filter_horizontal = ("collections",) list_display = ( "name", Loading trapper/trapper-project/trapper/apps/media_classification/serializers_tables.py +25 −8 Original line number Diff line number Diff line Loading @@ -297,6 +297,23 @@ class BaseTableSerializer(ABC): engine="pyarrow", ) def _ensure_expected_columns( self, df: pl.DataFrame, expected_columns: list[str] ) -> pl.DataFrame: missing = [col for col in expected_columns if col not in df.columns] if not missing: return df return df.with_columns( [ ( pl.lit(None).cast(self.schema_dtypes[col]) if col in self.schema_dtypes else pl.lit(None) ).alias(col) for col in missing ] ) def aggregate_observations( df: pl.DataFrame, Loading Loading @@ -961,21 +978,21 @@ class ObservationsSerializer(BaseTableSerializer): if camtrapdp: df = df.drop(["_id", "englishName"]) # Ensure all columns are in the correct order according to the schema expected_columns = list(self.schema_dtypes.keys()) if not camtrapdp: expected_columns.extend(["countNew", "englishName", "bboxes", "_id"]) # Ensure all expected columns are present df = self._ensure_expected_columns(df, expected_columns) # Reorder columns to match the schema df = df.select([pl.col(col) for col in expected_columns if col in df.columns]) df = df.select([pl.col(col) for col in expected_columns]) # Sort by deploymentID and timestamp df = df.sort(by=["deploymentID", "eventEnd"], descending=[False, False]) # Apply schema dtypes for col, dtype in self.schema_dtypes.items(): if col in df.columns: df = df.with_columns(pl.col(col).cast(dtype)) # FIXME: Ensure that count value is never set to 0 when observationType is in: Loading Loading @@ -1545,21 +1562,21 @@ class AIObservationsSerializer(ObservationsSerializer): # Process bboxes df = self._process_bboxes(df, keep_count_new=False, target_fps=target_fps) # Ensure all columns are in the correct order according to the schema expected_columns = list(self.schema_dtypes.keys()) if not camtrapdp: expected_columns.extend(["countNew", "englishName", "bboxes", "_id"]) # Ensure all expected columns are present df = self._ensure_expected_columns(df, expected_columns) # Reorder columns to match the schema df = df.select([pl.col(col) for col in expected_columns if col in df.columns]) df = df.select([pl.col(col) for col in expected_columns]) # Sort by deploymentID and timestamp df = df.sort(by=["deploymentID", "eventEnd"], descending=[False, False]) # apply schema dtypes for col, dtype in self.schema_dtypes.items(): if col in df.columns: df = df.with_columns(pl.col(col).cast(dtype)) return df trapper/trapper-project/trapper/apps/media_classification/tasks/ai_pipeline.py +1 −1 Original line number Diff line number Diff line Loading @@ -59,7 +59,7 @@ def start_ai_object_detection( if not ai_model: collection.ai_pipeline_status = UserRemoteTaskStatus.REJECTED logger.error("AI provider is not set for Citizen Science") logger.warning("AI provider is not set for Citizen Science") elif classification_ids: manager: TrapperAIProviderManager = get_ai_provider_manager(ai_model) Loading Loading
trapper/trapper-project/trapper/apps/accounts/admin.py +0 −1 Original line number Diff line number Diff line Loading @@ -504,7 +504,6 @@ class UserHttpUploaderAccountFilesAdmin(admin.ModelAdmin): list_filter = ("file_type", "uploaded_at", "account") search_fields = ("file_name", "account__user__username", "account__user__email") readonly_fields = ( "file", "file_size", "uploaded_at", "download_link", Loading
trapper/trapper-project/trapper/apps/geomap/views/views_rest.py +6 −2 Original line number Diff line number Diff line Loading @@ -196,7 +196,9 @@ class CSDeploymentView( def get_object(self): qs = self.get_deployments(self.get_classification_project(), self.request.user) return get_object_or_404(qs, pk=self.kwargs["deployment_pk"]) deployment_pk = self.kwargs["deployment_pk"] qs = qs.filter(pk=deployment_pk).distinct() return get_object_or_404(qs) @transaction.atomic def destroy(self, request, *args, **kwargs): Loading Loading @@ -256,4 +258,6 @@ class CSDeploymentUpdateTimestampsView( def get_object(self): qs = self.get_deployments(self.get_classification_project(), self.request.user) return get_object_or_404(qs, pk=self.kwargs["deployment_pk"]) deployment_pk = self.kwargs["deployment_pk"] qs = qs.filter(pk=deployment_pk).distinct() return get_object_or_404(qs)
trapper/trapper-project/trapper/apps/media_classification/admin.py +1 −11 Original line number Diff line number Diff line Loading @@ -151,18 +151,8 @@ class ProjectRoleInline(admin.TabularInline): raw_id_fields = ["user"] class ProjectCollectionInline(admin.TabularInline): model = ClassificationProjectCollection extra = 0 raw_id_fields = ("collection",) readonly_fields = ( "resources_count", "collection_storage", ) class ClassificationProjectAdmin(admin.ModelAdmin): inlines = [ProjectRoleInline, ProjectCollectionInline] inlines = [ProjectRoleInline] filter_horizontal = ("collections",) list_display = ( "name", Loading
trapper/trapper-project/trapper/apps/media_classification/serializers_tables.py +25 −8 Original line number Diff line number Diff line Loading @@ -297,6 +297,23 @@ class BaseTableSerializer(ABC): engine="pyarrow", ) def _ensure_expected_columns( self, df: pl.DataFrame, expected_columns: list[str] ) -> pl.DataFrame: missing = [col for col in expected_columns if col not in df.columns] if not missing: return df return df.with_columns( [ ( pl.lit(None).cast(self.schema_dtypes[col]) if col in self.schema_dtypes else pl.lit(None) ).alias(col) for col in missing ] ) def aggregate_observations( df: pl.DataFrame, Loading Loading @@ -961,21 +978,21 @@ class ObservationsSerializer(BaseTableSerializer): if camtrapdp: df = df.drop(["_id", "englishName"]) # Ensure all columns are in the correct order according to the schema expected_columns = list(self.schema_dtypes.keys()) if not camtrapdp: expected_columns.extend(["countNew", "englishName", "bboxes", "_id"]) # Ensure all expected columns are present df = self._ensure_expected_columns(df, expected_columns) # Reorder columns to match the schema df = df.select([pl.col(col) for col in expected_columns if col in df.columns]) df = df.select([pl.col(col) for col in expected_columns]) # Sort by deploymentID and timestamp df = df.sort(by=["deploymentID", "eventEnd"], descending=[False, False]) # Apply schema dtypes for col, dtype in self.schema_dtypes.items(): if col in df.columns: df = df.with_columns(pl.col(col).cast(dtype)) # FIXME: Ensure that count value is never set to 0 when observationType is in: Loading Loading @@ -1545,21 +1562,21 @@ class AIObservationsSerializer(ObservationsSerializer): # Process bboxes df = self._process_bboxes(df, keep_count_new=False, target_fps=target_fps) # Ensure all columns are in the correct order according to the schema expected_columns = list(self.schema_dtypes.keys()) if not camtrapdp: expected_columns.extend(["countNew", "englishName", "bboxes", "_id"]) # Ensure all expected columns are present df = self._ensure_expected_columns(df, expected_columns) # Reorder columns to match the schema df = df.select([pl.col(col) for col in expected_columns if col in df.columns]) df = df.select([pl.col(col) for col in expected_columns]) # Sort by deploymentID and timestamp df = df.sort(by=["deploymentID", "eventEnd"], descending=[False, False]) # apply schema dtypes for col, dtype in self.schema_dtypes.items(): if col in df.columns: df = df.with_columns(pl.col(col).cast(dtype)) return df
trapper/trapper-project/trapper/apps/media_classification/tasks/ai_pipeline.py +1 −1 Original line number Diff line number Diff line Loading @@ -59,7 +59,7 @@ def start_ai_object_detection( if not ai_model: collection.ai_pipeline_status = UserRemoteTaskStatus.REJECTED logger.error("AI provider is not set for Citizen Science") logger.warning("AI provider is not set for Citizen Science") elif classification_ids: manager: TrapperAIProviderManager = get_ai_provider_manager(ai_model) Loading