github.com/quickfeed/quickfeed@v0.0.0-20240507093252-ed8ca812a09c/qf/assignment.go (about)

     1  package qf
     2  
     3  import (
     4  	context "context"
     5  	"time"
     6  
     7  	"google.golang.org/protobuf/proto"
     8  )
     9  
    10  const (
    11  	days = time.Duration(24 * time.Hour)
    12  )
    13  
    14  // SinceDeadline returns the duration since the deadline.
    15  // A positive duration means the deadline has passed, whereas
    16  // a negative duration means the deadline has not yet passed.
    17  func (a *Assignment) SinceDeadline(now time.Time) time.Duration {
    18  	return now.Sub(a.GetDeadline().AsTime())
    19  }
    20  
    21  // WithTimeout returns a context with an execution timeout set to the assignment's specified
    22  // container timeout. If the assignment has no container timeout, the provided timeout value
    23  // is used instead.
    24  func (a *Assignment) WithTimeout(timeout time.Duration) (context.Context, context.CancelFunc) {
    25  	t := a.GetContainerTimeout()
    26  	if t > 0 {
    27  		timeout = time.Duration(t) * time.Minute
    28  	}
    29  	return context.WithTimeout(context.Background(), timeout)
    30  }
    31  
    32  // IsApproved returns an approved submission status if this assignment is already approved
    33  // for the latest submission, or if the score of the latest submission is sufficient
    34  // to autoapprove the assignment.
    35  func (a *Assignment) IsApproved(latest *Submission, score uint32) Submission_Status {
    36  	switch {
    37  	case latest.GetGroupID() > 0 && !a.IsGroupLab:
    38  		// If a group submits to a student assignment, ignore the submission.
    39  		return Submission_NONE
    40  	case latest.GetUserID() > 0 && a.IsGroupLab:
    41  		// If a student submits to a group assignment, ignore the submission.
    42  		return Submission_NONE
    43  	}
    44  	if a.GetAutoApprove() && score >= a.GetScoreLimit() {
    45  		return Submission_APPROVED
    46  	}
    47  	// keep existing status if already approved/revision/rejected
    48  	return latest.GetStatus()
    49  }
    50  
    51  // CloneWithoutSubmissions returns a deep copy of the assignment without submissions.
    52  func (a *Assignment) CloneWithoutSubmissions() *Assignment {
    53  	clone := proto.Clone(a).(*Assignment)
    54  	clone.Submissions = nil
    55  	return clone
    56  }
    57  
    58  // GradedManually returns true if the assignment will be graded manually.
    59  func (a *Assignment) GradedManually() bool {
    60  	return a.GetReviewers() > 0
    61  }