Loading common_lib/schema/types.py +37 −0 Original line number Diff line number Diff line Loading @@ -995,6 +995,14 @@ class IMilestoneModificationDetailsType(DjangoObjectType): ) class OpenSearchLogDetailsType(graphene.ObjectType): cmd = graphene.String(required=True) cmd_source = graphene.String(required=True) working_directory = graphene.String(required=True) username = graphene.String(required=True) container = graphene.String(required=True) class TActionLogDetails(graphene.Union): class Meta: types = [ Loading Loading @@ -1055,6 +1063,35 @@ class IActionLogType(DjangoObjectType): details = graphene.Field(IActionLogDetails, required=True) class OpenSearchActionLogType(graphene.ObjectType): class Meta: interfaces = (ActionLogInterface,) id = graphene.ID(required=True) timestamp = graphene.DateTime(required=True) type = graphene.Field(LogTypeEnum, required=True) channel = graphene.Field(ChannelInterface, required=True) user = graphene.Field(_("UserInterface")) team_id = graphene.ID(required=True) team = graphene.Field(TeamType, required=True) previous_log_id = graphene.ID() previous_log = graphene.Field(_("ActionLogInterface")) instructor_comment = graphene.Field(InstructorCommentType) next_logs = graphene.List( _("ActionLogInterface"), required=True, description="Prefer to not use this field in bulk queries", ) in_exercise_time = graphene.Int(required=True) details = graphene.Field(OpenSearchLogDetailsType, required=True) def resolve_log_type(self, info): return self.type def resolve_next_logs(self, info): return self.next_logs.all() if hasattr(self, "next_logs") else [] class EmailThreadType(DjangoObjectType): class Meta: model = EmailThread Loading running_exercise/graphql_inputs.py +17 −0 Original line number Diff line number Diff line Loading @@ -176,3 +176,20 @@ class ActionLogsFilterType(ActionLogsFilterBase, graphene.ObjectType): class ActionLogsFilterInput(ActionLogsFilterBase, graphene.InputObjectType): pass class OpenSearchActionLogsFilterBase: team_ids = graphene.List(graphene.NonNull(graphene.ID), required=True) newest_first = graphene.Boolean(required=False, default_value=False) class OpenSearchActionLogsFilterType( OpenSearchActionLogsFilterBase, graphene.ObjectType ): pass class OpenSearchActionLogsFilterInput( OpenSearchActionLogsFilterBase, graphene.InputObjectType ): pass running_exercise/models.py +1 −0 Original line number Diff line number Diff line Loading @@ -243,6 +243,7 @@ class LogType(models.TextChoices): CONFIRMATION = "CONFIRMATION" FILE_DOWNLOAD = "FILE_DOWNLOAD" MILESTONE_MODIFICATION = "MILESTONE_MODIFICATION" OPENSEARCH_LOG = "OPENSEARCH_LOG" @staticmethod def get_type(details: DetailsUnion) -> str: Loading running_exercise/schema/query.py +28 −1 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ from common_lib.schema.types import ( EmailThreadType, EmailParticipantType, EmailTemplateType, OpenSearchActionLogType, TeamType, TeamQuestionnaireStateInterface, KeyValueType, Loading @@ -42,10 +43,14 @@ from exercise_definition.models import ( Tool, FileInfo, ) from running_exercise.graphql_inputs import ActionLogsFilterInput from running_exercise.graphql_inputs import ( ActionLogsFilterInput, OpenSearchActionLogsFilterInput, ) from running_exercise.lib.email_client import EmailClient from running_exercise.lib.exercise_loop import ExerciseLoop from running_exercise.lib.kv_store import KVStore from running_exercise.lib.opensearch_client import fetch_opensearch_logs from running_exercise.lib.utils import can_show_instructor_comments from running_exercise.models import ActionLog, EmailThread, InstructorComment from user.models import User Loading Loading @@ -74,6 +79,14 @@ class Query(graphene.ObjectType): log_filter=graphene.Argument(ActionLogsFilterInput, required=True), description="Retrieve all action logs for the specific teams based on the filter", ) team_open_search_action_logs = graphene.List( graphene.NonNull(OpenSearchActionLogType), required=True, log_filter=graphene.Argument( OpenSearchActionLogsFilterInput, required=True ), description="Retrieve all action logs for the specific teams based on the filter from OpenSearch", ) team_milestone = graphene.Field( graphene.NonNull(MilestoneStateType), milestone_state_id=graphene.ID(required=True), Loading Loading @@ -277,6 +290,20 @@ class Query(graphene.ObjectType): return logs @protected(User.AuthGroup.INSTRUCTOR) def resolve_team_open_search_action_logs( self, info, log_filter: OpenSearchActionLogsFilterInput, ) -> QuerySet[OpenSearchActionLogType]: check_teams_access(info.context, log_filter.team_ids) logs = fetch_opensearch_logs( log_filter.team_ids, log_filter.newest_first ) return logs @protected(User.AuthGroup.INSTRUCTOR) def resolve_team_milestone( self, info, milestone_state_id: str Loading Loading
common_lib/schema/types.py +37 −0 Original line number Diff line number Diff line Loading @@ -995,6 +995,14 @@ class IMilestoneModificationDetailsType(DjangoObjectType): ) class OpenSearchLogDetailsType(graphene.ObjectType): cmd = graphene.String(required=True) cmd_source = graphene.String(required=True) working_directory = graphene.String(required=True) username = graphene.String(required=True) container = graphene.String(required=True) class TActionLogDetails(graphene.Union): class Meta: types = [ Loading Loading @@ -1055,6 +1063,35 @@ class IActionLogType(DjangoObjectType): details = graphene.Field(IActionLogDetails, required=True) class OpenSearchActionLogType(graphene.ObjectType): class Meta: interfaces = (ActionLogInterface,) id = graphene.ID(required=True) timestamp = graphene.DateTime(required=True) type = graphene.Field(LogTypeEnum, required=True) channel = graphene.Field(ChannelInterface, required=True) user = graphene.Field(_("UserInterface")) team_id = graphene.ID(required=True) team = graphene.Field(TeamType, required=True) previous_log_id = graphene.ID() previous_log = graphene.Field(_("ActionLogInterface")) instructor_comment = graphene.Field(InstructorCommentType) next_logs = graphene.List( _("ActionLogInterface"), required=True, description="Prefer to not use this field in bulk queries", ) in_exercise_time = graphene.Int(required=True) details = graphene.Field(OpenSearchLogDetailsType, required=True) def resolve_log_type(self, info): return self.type def resolve_next_logs(self, info): return self.next_logs.all() if hasattr(self, "next_logs") else [] class EmailThreadType(DjangoObjectType): class Meta: model = EmailThread Loading
running_exercise/graphql_inputs.py +17 −0 Original line number Diff line number Diff line Loading @@ -176,3 +176,20 @@ class ActionLogsFilterType(ActionLogsFilterBase, graphene.ObjectType): class ActionLogsFilterInput(ActionLogsFilterBase, graphene.InputObjectType): pass class OpenSearchActionLogsFilterBase: team_ids = graphene.List(graphene.NonNull(graphene.ID), required=True) newest_first = graphene.Boolean(required=False, default_value=False) class OpenSearchActionLogsFilterType( OpenSearchActionLogsFilterBase, graphene.ObjectType ): pass class OpenSearchActionLogsFilterInput( OpenSearchActionLogsFilterBase, graphene.InputObjectType ): pass
running_exercise/models.py +1 −0 Original line number Diff line number Diff line Loading @@ -243,6 +243,7 @@ class LogType(models.TextChoices): CONFIRMATION = "CONFIRMATION" FILE_DOWNLOAD = "FILE_DOWNLOAD" MILESTONE_MODIFICATION = "MILESTONE_MODIFICATION" OPENSEARCH_LOG = "OPENSEARCH_LOG" @staticmethod def get_type(details: DetailsUnion) -> str: Loading
running_exercise/schema/query.py +28 −1 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ from common_lib.schema.types import ( EmailThreadType, EmailParticipantType, EmailTemplateType, OpenSearchActionLogType, TeamType, TeamQuestionnaireStateInterface, KeyValueType, Loading @@ -42,10 +43,14 @@ from exercise_definition.models import ( Tool, FileInfo, ) from running_exercise.graphql_inputs import ActionLogsFilterInput from running_exercise.graphql_inputs import ( ActionLogsFilterInput, OpenSearchActionLogsFilterInput, ) from running_exercise.lib.email_client import EmailClient from running_exercise.lib.exercise_loop import ExerciseLoop from running_exercise.lib.kv_store import KVStore from running_exercise.lib.opensearch_client import fetch_opensearch_logs from running_exercise.lib.utils import can_show_instructor_comments from running_exercise.models import ActionLog, EmailThread, InstructorComment from user.models import User Loading Loading @@ -74,6 +79,14 @@ class Query(graphene.ObjectType): log_filter=graphene.Argument(ActionLogsFilterInput, required=True), description="Retrieve all action logs for the specific teams based on the filter", ) team_open_search_action_logs = graphene.List( graphene.NonNull(OpenSearchActionLogType), required=True, log_filter=graphene.Argument( OpenSearchActionLogsFilterInput, required=True ), description="Retrieve all action logs for the specific teams based on the filter from OpenSearch", ) team_milestone = graphene.Field( graphene.NonNull(MilestoneStateType), milestone_state_id=graphene.ID(required=True), Loading Loading @@ -277,6 +290,20 @@ class Query(graphene.ObjectType): return logs @protected(User.AuthGroup.INSTRUCTOR) def resolve_team_open_search_action_logs( self, info, log_filter: OpenSearchActionLogsFilterInput, ) -> QuerySet[OpenSearchActionLogType]: check_teams_access(info.context, log_filter.team_ids) logs = fetch_opensearch_logs( log_filter.team_ids, log_filter.newest_first ) return logs @protected(User.AuthGroup.INSTRUCTOR) def resolve_team_milestone( self, info, milestone_state_id: str Loading