types

package
v0.0.0-...-b1d63b3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 10, 2024 License: AGPL-3.0 Imports: 17 Imported by: 0

Documentation

Index

Constants

View Source
const (
	TranscriptEventCountLimit = 500
	TranscriptDataLimit       = 1e5
	OpenCommitTimeout         = 6 * time.Hour
	SignedCommitTimeout       = 15 * time.Minute
	CookieName                = "codegrinder"
)
View Source
const MaxDaycareRequestAge = 15 * time.Minute

MaxDaycareRequestAge is the maximum age of a daycare-signed commit to be saved. Any commit older than this will be rejected.

View Source
const MaxDetailsLen = 50e3

Variables

View Source
var BeginningOfTime = time.Date(2016, 1, 1, 0, 0, 0, 0, time.UTC)
View Source
var CurrentVersion = Version{
	Version:                  "2.6.4",
	GrindVersionRequired:     "2.6.4",
	GrindVersionRecommended:  "2.6.4",
	ThonnyVersionRecommended: "2.6.15",
	ThonnyVersionRequired:    "2.6.9",
}
View Source
var ProblemStepDirectoryWhitelist = map[string]bool{
	"inputs":  true,
	"outputs": true,
	"doc":     true,
}

problem files in these directories do not have line endings cleaned up

Functions

This section is empty.

Types

type Answer

type Answer struct {
	Answer string  `json:"answer"`
	Points float64 `json:"points"`
}

type Assignment

type Assignment struct {
	ID                 int64                `json:"id" meddler:"id,pk"`
	CourseID           int64                `json:"courseID" meddler:"course_id"`
	ProblemSetID       int64                `json:"problemSetID" meddler:"problem_set_id,zeroisnull"`
	UserID             int64                `json:"userID" meddler:"user_id"`
	Roles              string               `json:"roles" meddler:"roles"`
	Instructor         bool                 `json:"instructor" meddler:"instructor"`
	RawScores          map[string][]float64 `json:"rawScores" meddler:"raw_scores,json"`
	Score              float64              `json:"score" meddler:"score,zeroisnull"`
	GradeID            string               `json:"-" meddler:"grade_id,zeroisnull"`
	LtiID              string               `json:"-" meddler:"lti_id"`
	CanvasTitle        string               `json:"canvasTitle" meddler:"canvas_title"`
	CanvasID           int64                `json:"canvasID" meddler:"canvas_id"`
	CanvasAPIDomain    string               `json:"-" meddler:"canvas_api_domain"`
	OutcomeURL         string               `json:"-" meddler:"outcome_url"`
	OutcomeExtURL      string               `json:"-" meddler:"outcome_ext_url"`
	OutcomeExtAccepted string               `json:"-" meddler:"outcome_ext_accepted"`
	FinishedURL        string               `json:"-" meddler:"finished_url"`
	ConsumerKey        string               `json:"consumerKey" meddler:"consumer_key"`
	UnlockAt           *time.Time           `json:"unlockAt" meddler:"unlock_at,localtime"`
	DueAt              *time.Time           `json:"dueAt" meddler:"due_at,localtime"`
	LockAt             *time.Time           `json:"lockAt" meddler:"lock_at,localtime"`
	CreatedAt          time.Time            `json:"createdAt" meddler:"created_at,localtime"`
	UpdatedAt          time.Time            `json:"updatedAt" meddler:"updated_at,localtime"`
}

Assignment represents a single instance of a problem set for a student in a course. Many commits (attempts to solve a step of a problem in the set) are linked to an assignment.

func (*Assignment) ComputeScore

func (assignment *Assignment) ComputeScore(majorWeights map[string]float64, minorWeights map[string][]float64) (float64, error)

func (*Assignment) IsInstructorRole

func (asst *Assignment) IsInstructorRole() bool

isInstructorRole returns true if the given LTI Roles field indicates this user is an instructor for a specific course.

func (*Assignment) SetMinorScore

func (assignment *Assignment) SetMinorScore(major string, minor int, score float64)

type Commit

type Commit struct {
	ID           int64             `json:"id" meddler:"id,pk"`
	AssignmentID int64             `json:"assignmentID" meddler:"assignment_id"`
	ProblemID    int64             `json:"problemID" meddler:"problem_id"`
	Step         int64             `json:"step" meddler:"step"` // note: one-based
	Action       string            `json:"action" meddler:"action,zeroisnull"`
	Note         string            `json:"note" meddler:"note,zeroisnull"`
	Files        map[string][]byte `json:"files" meddler:"files,json"`
	Transcript   []*EventMessage   `json:"transcript,omitempty" meddler:"transcript,json"`
	ReportCard   *ReportCard       `json:"reportCard" meddler:"report_card,json"`
	Score        float64           `json:"score" meddler:"score,zeroisnull"`
	CreatedAt    time.Time         `json:"createdAt" meddler:"created_at,localtime"`
	UpdatedAt    time.Time         `json:"updatedAt" meddler:"updated_at,localtime"`
}

Commit defines an attempt at solving one step of a Problem.

func (*Commit) ComputeSignature

func (commit *Commit) ComputeSignature(secret, problemTypeSignature, problemSignature, daycareHost string, userID int64) string

func (*Commit) DumpTranscript

func (commit *Commit) DumpTranscript(w io.Writer) error

func (*Commit) FilterIncoming

func (commit *Commit) FilterIncoming(whitelist map[string]bool)

filter out files in subdirectories/not on whitelist, and clean up line endings

func (*Commit) Normalize

func (commit *Commit) Normalize(now time.Time, whitelist map[string]bool) error

type CommitBundle

type CommitBundle struct {
	ProblemType          *ProblemType   `json:"problemType"`
	ProblemTypeSignature string         `json:"problemTypeSignature,omitempty"`
	Problem              *Problem       `json:"problem"`
	ProblemSteps         []*ProblemStep `json:"problemSteps"`
	ProblemSignature     string         `json:"problemSignature,omitempty"`
	Action               string         `json:"action"`
	Hostname             string         `json:"hostname,omitempty"`
	UserID               int64          `json:"userID"`
	Commit               *Commit        `json:"commit"`
	CommitSignature      string         `json:"commitSignature,omitempty"`
}

type Course

type Course struct {
	ID        int64     `json:"id" meddler:"id,pk"`
	Name      string    `json:"name" meddler:"name"`
	Label     string    `json:"label" meddler:"lti_label"`
	LtiID     string    `json:"ltiID" meddler:"lti_id"`
	CanvasID  int64     `json:"canvasID" meddler:"canvas_id"`
	CreatedAt time.Time `json:"createdAt" meddler:"created_at,localtime"`
	UpdatedAt time.Time `json:"updatedAt" meddler:"updated_at,localtime"`
}

Course represents a single instance of a course as defined by LTI.

type DaycareRequest

type DaycareRequest struct {
	CommitBundle *CommitBundle `json:"commitBundle,omitempty"`
	Stdin        []byte        `json:"stdin,omitempty"`
	CloseStdin   bool          `json:"closeStdin,omitempty"`
}

DaycareRequest represents a single request from a client to the daycare. These objects are streamed across a websockets connection.

type DaycareResponse

type DaycareResponse struct {
	CommitBundle *CommitBundle `json:"commitBundle,omitempty"`
	Event        *EventMessage `json:"event,omitempty"`
	Error        string        `json:"error,omitempty"`
}

DaycareResponse represents a single response from the daycare back to a client. These objects are streamed across a websockets connection.

type EventMessage

type EventMessage struct {
	Time        time.Time         `json:"time"`
	Event       string            `json:"event"`
	ExecCommand []string          `json:"execCommand,omitempty"`
	ExitStatus  int               `json:"exitStatus,omitempty"`
	StreamData  []byte            `json:"streamData,omitempty"`
	Error       string            `json:"error,omitempty"`
	ReportCard  *ReportCard       `json:"reportCard,omitempty"`
	Files       map[string][]byte `json:"files,omitempty"`
}

EventMessage follows one of these forms:

exec ExecCommand
exit ExitStatus
stdin StreamData
stdout StreamData
stderr StreamData
stdinclosed
error Error
reportcard ReportCard
files Files

func (*EventMessage) Dump

func (e *EventMessage) Dump() string

func (*EventMessage) String

func (e *EventMessage) String() string

type Problem

type Problem struct {
	ID        int64     `json:"id" meddler:"id,pk"`
	Unique    string    `json:"unique" meddler:"unique_id"`
	Note      string    `json:"note" meddler:"note"`
	Tags      []string  `json:"tags" meddler:"tags,json"`
	Options   []string  `json:"options" meddler:"options,json"`
	CreatedAt time.Time `json:"createdAt" meddler:"created_at,localtime"`
	UpdatedAt time.Time `json:"updatedAt" meddler:"updated_at,localtime"`
}

func (*Problem) ComputeSignature

func (problem *Problem) ComputeSignature(secret string, steps []*ProblemStep) string

func (*Problem) Normalize

func (problem *Problem) Normalize(now time.Time, steps []*ProblemStep) error

type ProblemBundle

type ProblemBundle struct {
	ProblemTypes          map[string]*ProblemType `json:"problemTypes"`
	ProblemTypeSignatures map[string]string       `json:"problemTypeSignatures,omitempty"`
	Problem               *Problem                `json:"problem"`
	ProblemSteps          []*ProblemStep          `json:"problemSteps"`
	ProblemSignature      string                  `json:"problemSignature,omitempty"`
	Hostname              string                  `json:"hostname"`
	UserID                int64                   `json:"userID"`
	Commits               []*Commit               `json:"commits"`
	CommitSignatures      []string                `json:"commitSignatures,omitempty"`
}

type ProblemSet

type ProblemSet struct {
	ID        int64     `json:"id" meddler:"id,pk"`
	Unique    string    `json:"unique" meddler:"unique_id"`
	Note      string    `json:"note" meddler:"note"`
	Tags      []string  `json:"tags" meddler:"tags,json"`
	CreatedAt time.Time `json:"createdAt" meddler:"created_at,localtime"`
	UpdatedAt time.Time `json:"updatedAt" meddler:"updated_at,localtime"`
}

func (*ProblemSet) Normalize

func (set *ProblemSet) Normalize(now time.Time) error

type ProblemSetBundle

type ProblemSetBundle struct {
	ProblemSet         *ProblemSet          `json:"problemSet"`
	ProblemSetProblems []*ProblemSetProblem `json:"problemSetProblems"`
}

type ProblemSetProblem

type ProblemSetProblem struct {
	ProblemSetID int64   `json:"problemSetID,omitempty" meddler:"problem_set_id"`
	ProblemID    int64   `json:"problemID" meddler:"problem_id"`
	Weight       float64 `json:"weight" meddler:"weight"`
}

type ProblemStep

type ProblemStep struct {
	ProblemID    int64             `json:"problemID" meddler:"problem_id"`
	Step         int64             `json:"step" meddler:"step"` // note: one-based
	ProblemType  string            `json:"problemType" meddler:"problem_type"`
	Note         string            `json:"note" meddler:"note"`
	Instructions string            `json:"instructions" meddler:"instructions"`
	Weight       float64           `json:"weight" meddler:"weight"`
	Files        map[string][]byte `json:"files" meddler:"files,json"`
	Whitelist    map[string]bool   `json:"whitelist" meddler:"whitelist,json"`
	Solution     map[string][]byte `json:"solution,omitempty" meddler:"solution,json"`
}

ProblemStep represents a single step of a problem. Anything in the root directory of Files is added to the working directory, possibly overwriting existing content. The subdirectory contents of Files replace all subdirectory contents in the problem from earlier steps.

func (*ProblemStep) BuildInstructions

func (step *ProblemStep) BuildInstructions() (string, error)

buildInstructions builds the instructions for a problem step as a single html document. Markdown is processed and images are inlined.

func (*ProblemStep) Normalize

func (step *ProblemStep) Normalize(n int64) error

fix line endings

type ProblemType

type ProblemType struct {
	Name    string                        `json:"name" meddler:"name"`
	Image   string                        `json:"image" meddler:"image"`
	Files   map[string][]byte             `json:"files,omitempty" meddler:"-"`
	Actions map[string]*ProblemTypeAction `json:"actions" meddler:"-"`
}

ProblemType defines one type of problem.

func (*ProblemType) ComputeSignature

func (problemType *ProblemType) ComputeSignature(secret string) string

type ProblemTypeAction

type ProblemTypeAction struct {
	ProblemType string `json:"problemType" meddler:"problem_type"`
	Action      string `json:"action,omitempty" meddler:"action"`
	Command     string `json:"command,omitempty" meddler:"command"`
	Parser      string `json:"parser,omitempty" meddler:"parser,zeroisnull"`
	Message     string `json:"message,omitempty" meddler:"message"`
	Interactive bool   `json:"interactive,omitempty" meddler:"interactive"`

	MaxCPU      int64 `json:"maxCPU" meddler:"max_cpu"`
	MaxSession  int64 `json:"maxSession" meddler:"max_session"`
	MaxTimeout  int64 `json:"maxTimeout" meddler:"max_timeout"`
	MaxFD       int64 `json:"maxFD" meddler:"max_fd"`
	MaxFileSize int64 `json:"maxFileSize" meddler:"max_file_size"`
	MaxMemory   int64 `json:"maxMemory" meddler:"max_memory"`
	MaxThreads  int64 `json:"maxThreads" meddler:"max_threads"`
}

ProblemTypeAction defines the labels, parser, interactivity, and handler for a single problem type action.

type Question

type Question struct {
	ID               int64      `json:"id" meddler:"id,pk"`
	QuizID           int64      `json:"quizID" meddler:"quiz_id"`
	Number           int64      `json:"number" meddler:"question_number"` // note: 1-based
	Note             string     `json:"note" meddler:"note"`
	Weight           float64    `json:"weight" meddler:"weight"`
	PointsForAttempt float64    `json:"pointsForAttempt" meddler:"points_for_attempt"`
	IsMultipleChoice bool       `json:"isMultipleChoice" meddler:"is_multiple_choice"`
	Answers          []Answer   `json:"answers" meddler:"answers,json"`
	ClosedAt         *time.Time `json:"closedAt" meddler:"closed_at,localtime"`
	CreatedAt        time.Time  `json:"createdAt" meddler:"created_at,localtime"`
	UpdatedAt        time.Time  `json:"updatedAt" meddler:"updated_at,localtime"`
}

Question represents a single interactive quiz question.

func (*Question) HideAnswersUnlessClosed

func (question *Question) HideAnswersUnlessClosed()

func (*Question) IsClosed

func (question *Question) IsClosed() bool

type QuestionPatch

type QuestionPatch struct {
	Note             *string    `json:"note"`
	Weight           *float64   `json:"weight"`
	PointsForAttempt *float64   `json:"pointsForAttempt"`
	IsMultipleChoice *bool      `json:"isMultipleChoice"`
	Answers          *[]Answer  `json:"answers"`
	ClosedAt         *time.Time `json:"closedAt"`
}

type Quiz

type Quiz struct {
	ID                     int64     `json:"id" meddler:"id,pk"`
	AssignmentID           int64     `json:"assignmentID" meddler:"assignment_id"` // creator
	LtiID                  string    `json:"-" meddler:"lti_id"`
	Note                   string    `json:"note" meddler:"note"`
	Weight                 float64   `json:"weight" meddler:"weight"`
	ParticipationThreshold float64   `json:"participationThreshold" meddler:"participation_threshold"`
	ParticipationPercent   float64   `json:"participationPercent" meddler:"participation_percent"`
	IsGraded               bool      `json:"isGraded" meddler:"is_graded"`
	CreatedAt              time.Time `json:"createdAt" meddler:"created_at,localtime"`
	UpdatedAt              time.Time `json:"updatedAt" meddler:"updated_at,localtime"`
}

Quiz represents a single session of interactive student quizzes, usually from a single class period.

type QuizPatch

type QuizPatch struct {
	Note                   *string  `json:"note"`
	Weight                 *float64 `json:"weight"`
	ParticipationThreshold *float64 `json:"participationThreshold"`
	ParticipationPercent   *float64 `json:"participationPercent"`
	IsGraded               *bool    `json:"isGraded"`
}

type ReportCard

type ReportCard struct {
	Passed   bool                `json:"passed"`
	Note     string              `json:"note"`
	Duration time.Duration       `json:"duration"`
	Results  []*ReportCardResult `json:"results"`
}

ReportCard gives the results of a graded run

func NewReportCard

func NewReportCard() *ReportCard

func (*ReportCard) AddFailedResult

func (elt *ReportCard) AddFailedResult(name, details, context string) *ReportCardResult

func (*ReportCard) AddPassedResult

func (elt *ReportCard) AddPassedResult(name, details string) *ReportCardResult

func (*ReportCard) AddTime

func (elt *ReportCard) AddTime(duration time.Duration)

func (*ReportCard) ComputeScore

func (elt *ReportCard) ComputeScore() float64

func (*ReportCard) Failf

func (elt *ReportCard) Failf(note string, params ...interface{})

func (*ReportCard) LogAndFailf

func (elt *ReportCard) LogAndFailf(note string, params ...interface{})

type ReportCardResult

type ReportCardResult struct {
	Name    string `json:"name"`
	Outcome string `json:"outcome"`
	Details string `json:"details,omitempty"`
	Context string `json:"context,omitempty"`
}

ReportCardResult Outcomes:

passed
failed
error
skipped

Details: a multi-line message that should

be displayed in a monospace font

Context:

path/to/file.py:line#

type Response

type Response struct {
	ID           int64     `json:"id" meddler:"id,pk"`
	AssignmentID int64     `json:"assignmentID" meddler:"assignment_id"`
	QuestionID   int64     `json:"questionID" meddler:"question_id"`
	Response     string    `json:"response" meddler:"response"`
	CreatedAt    time.Time `json:"createdAt" meddler:"created_at,localtime"`
	UpdatedAt    time.Time `json:"updatedAt" meddler:"updated_at,localtime"`
}

Response represents a student response to a single question.

type User

type User struct {
	ID             int64     `json:"id" meddler:"id,pk"`
	Name           string    `json:"name" meddler:"name"`
	Email          string    `json:"email" meddler:"email"`
	LtiID          string    `json:"ltiID" meddler:"lti_id"`
	ImageURL       string    `json:"imageURL" meddler:"lti_image_url"`
	CanvasLogin    string    `json:"canvasLogin" meddler:"canvas_login"`
	CanvasID       int64     `json:"canvasID" meddler:"canvas_id"`
	Author         bool      `json:"author" meddler:"author"`
	Admin          bool      `json:"admin" meddler:"admin"`
	CreatedAt      time.Time `json:"createdAt" meddler:"created_at,localtime"`
	UpdatedAt      time.Time `json:"updatedAt" meddler:"updated_at,localtime"`
	LastSignedInAt time.Time `json:"lastSignedInAt" meddler:"last_signed_in_at,localtime"`
}

User represents a single user as defined by LTI.

type Version

type Version struct {
	Version                  string `json:"version"`
	GrindVersionRequired     string `json:"grindVersionRequired"`
	GrindVersionRecommended  string `json:"grindVersionRecommended"`
	ThonnyVersionRequired    string `json:"thonnyVersionRequired"`
	ThonnyVersionRecommended string `json:"thonnyVersionRecommended"`
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL