kilonova

package module
v0.25.0 Latest Latest
Warning

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

Go to latest
Published: May 18, 2024 License: AGPL-3.0 Imports: 20 Imported by: 0

README

Kilonova

GoDoc

Kilonova is a (work-in-progress) platform for competitive programming.

You can see the Changelog here.

Documentation

Index

Constants

View Source
const (
	PreferredThemeNone  = ""
	PreferredThemeLight = "light"
	PreferredThemeDark  = "dark"
)
View Source
const MaxScoreRoundingPlaces = 4
View Source
const Version = "v0.25.0"

Variables

View Source
var (
	DefaultSourceSize   = config.GenFlag[int]("behavior.problem.default_source_size", 30000, "Default maximum source code size for problems")
	ErrAttachmentExists = Statusf(400, "Attachment with that name already exists!")
)
View Source
var (
	ErrNoUpdates       = Statusf(400, "No updates specified")
	ErrMissingRequired = Statusf(400, "Missing required fields")

	ErrNotFound     = Statusf(404, "Not found")
	ErrUnknownError = Statusf(500, "Unknown error occured")

	ErrFeatureDisabled = Statusf(400, "Feature disabled by administrator")

	ErrContextCanceled = WrapError(context.Canceled, "Context canceled")
)
View Source
var (
	ErrNotExist = Statusf(404, "File doesn't exist")
)

Functions

func CheckPwdHash

func CheckPwdHash(password, hash string) bool

func GetText

func GetText(lang, line string, args ...any) string

func GetZapCore

func GetZapCore(debug bool, color bool, out io.Writer) zapcore.Core

func HashPassword

func HashPassword(password string) (string, error)

func MakeSlug

func MakeSlug(org string) string

func RandomSaltedString added in v0.25.0

func RandomSaltedString(salt string) string

func RandomString

func RandomString(size int) string

RandomString returns a new string of a specified size containing only [a-zA-Z0-9] characters

func RandomStringChars added in v0.25.0

func RandomStringChars(size int, characters string) string

RandomString returns a new string of a specified size containing only characters from the given string

func StatusData

func StatusData(w http.ResponseWriter, status string, retData any, statusCode int)

func TranslationKeyExists

func TranslationKeyExists(line string) bool

func ValidTagType

func ValidTagType(t TagType) bool

Types

type Attachment

type Attachment struct {
	ID        int       `json:"id"`
	CreatedAt time.Time `json:"created_at"`
	Visible   bool      `json:"visible"`
	Private   bool      `json:"private"`
	Exec      bool      `json:"exec"`

	LastUpdatedAt time.Time `json:"last_updated_at"`
	LastUpdatedBy *int      `json:"last_updated_by"`

	Name string `json:"name"`
	// Data []byte `json:"data,omitempty"`
	Size int `json:"data_size"`
}

type AttachmentFilter

type AttachmentFilter struct {
	ID         *int
	IDs        []int
	ProblemID  *int
	BlogPostID *int

	Visible *bool
	Private *bool
	Exec    *bool
	Name    *string

	Limit  int
	Offset int
}

Should be used only for interacting with db from sudoapi

type AttachmentUpdate

type AttachmentUpdate struct {
	Visible *bool   `json:"visible"`
	Private *bool   `json:"private"`
	Exec    *bool   `json:"exec"`
	Name    *string `json:"name"`
}

type AuditLog

type AuditLog struct {
	ID        int        `json:"id"`
	LogTime   time.Time  `json:"log_time"`
	SystemLog bool       `json:"system_log"`
	Message   string     `json:"message"`
	Author    *UserBrief `json:"author"`
}

type BlogPost

type BlogPost struct {
	ID        int       `json:"id"`
	CreatedAt time.Time `json:"created_at"`
	AuthorID  int       `json:"author_id"`

	Title string `json:"title"`

	Slug    string `json:"slug"` // unique, used in URL
	Visible bool   `json:"visible"`

	PublishedAt *time.Time `json:"published_at"`
}

Just a sketch of the concepts behind a blog functionality

type BlogPostFilter

type BlogPostFilter struct {
	ID       *int  `json:"id"`
	IDs      []int `json:"ids"`
	AuthorID *int  `json:"author_id"`

	Slug *string `json:"slug"`

	Limit  int `json:"limit"`
	Offset int `json:"offset"`

	Look        bool       `json:"-"`
	LookingUser *UserBrief `json:"-"`

	// Check posts that have attachment with that ID
	// Currently used for logging statement changes
	AttachmentID *int `json:"-"`

	Ordering  string `json:"ordering"`
	Ascending bool   `json:"ascending"`
}

type BlogPostUpdate

type BlogPostUpdate struct {
	Slug    *string `json:"slug"`
	Visible *bool   `json:"visible"`
	Title   *string `json:"title"`
}

type Contest

type Contest struct {
	ID        int          `json:"id"`
	CreatedAt time.Time    `json:"created_at"`
	Name      string       `json:"name"`
	Editors   []*UserBrief `json:"editors"`
	Testers   []*UserBrief `json:"testers"`

	Description string `json:"description"`

	// PublicJoin indicates whether a user can freely join a contest
	// or he needs to be manually added
	PublicJoin bool `json:"public_join"`

	// RegisterDuringContest indicates whether a user can join a contest while it's running
	// It is useless without PublicJoin set to true
	RegisterDuringContest bool `json:"register_during_contest"`

	// Visible indicates whether a contest can be seen by others
	// Contestants may be able to see the contest
	Visible bool `json:"hidden"`

	// PublicLeaderboard controls whether the contest's leaderboard
	// is viewable by everybody or just admins
	PublicLeaderboard bool `json:"public_leaderboard"`

	LeaderboardStyle      LeaderboardType `json:"leaderboard_style"`
	LeaderboardFreeze     *time.Time      `json:"leaderboard_freeze"`
	ICPCSubmissionPenalty int             `json:"icpc_submission_penalty"`

	LeaderboardAdvancedFilter bool `json:"leaderboard_advanced_filter"`

	SubmissionCooldown time.Duration `json:"submission_cooldown"`
	QuestionCooldown   time.Duration `json:"question_cooldown"`

	StartTime time.Time `json:"start_time"`
	EndTime   time.Time `json:"end_time"`

	// PerUserTime records the number of seconds a user has in an USACO-style participation
	// Setting it to 0 will make contests behave "normally"
	PerUserTime int `json:"per_user_time"`

	Type ContestType `json:"type"`

	// MaxSubs is the maximum number of submissions
	// that someone is allowed to send to a problem during a contest
	// < 0 => no limit
	MaxSubs int `json:"max_subs"`
}

func (*Contest) Ended

func (c *Contest) Ended() bool

func (*Contest) Running

func (c *Contest) Running() bool

func (*Contest) Started

func (c *Contest) Started() bool

type ContestAnnouncement

type ContestAnnouncement struct {
	ID        int       `json:"id"`
	CreatedAt time.Time `json:"created_at"`
	ContestID int       `json:"contest_id"`
	Text      string    `json:"text"`
}

type ContestFilter

type ContestFilter struct {
	ID          *int       `json:"id"`
	IDs         []int      `json:"ids"`
	Look        bool       `json:"-"`
	LookingUser *UserBrief `json:"-"`

	ProblemID *int `json:"problem_id"`

	// Shows contests in which user with this ID was registered
	ContestantID *int `json:"contestant_id"`

	// Shows contests in which user with this ID is an editor
	EditorID *int `json:"editor_id"`

	Future  bool `json:"future"`
	Running bool `json:"running"`
	Ended   bool `json:"ended"`

	Type ContestType `json:"type"`

	// Filters for that user the *important* contests:
	//   - Official contests
	//   - Virtual contests with participation
	//   - Virtual contests the user organizes (editor/tester)
	// This is used in filtering the contests for the main page
	ImportantContestsUID *int `json:"important_contest_uid"`

	Since *time.Time `json:"-"`

	Limit  int `json:"limit"`
	Offset int `json:"offset"`

	Ordering  string `json:"ordering"`
	Ascending bool   `json:"ascending"`
}

type ContestInvitation

type ContestInvitation struct {
	ID string `json:"id"`

	CreatedAt time.Time `json:"created_at" db:"created_at"`
	ContestID int       `json:"contest_id" db:"contest_id"`
	CreatorID *int      `json:"creator_id" db:"creator_id"`

	RedeemCount int  `json:"redeem_count" db:"redeem_cnt"`
	MaxCount    *int `json:"max_invitation_count" db:"max_invitation_cnt"`

	Expired bool `json:"expired"`
}

func (*ContestInvitation) Invalid added in v0.25.0

func (ci *ContestInvitation) Invalid() bool

type ContestLeaderboard

type ContestLeaderboard struct {
	ProblemOrder []int               `json:"problem_ordering"`
	ProblemNames map[int]string      `json:"problem_names"`
	Entries      []*LeaderboardEntry `json:"entries"`

	AdvancedFilter bool `json:"advanced_filter"`

	FreezeTime *time.Time      `json:"freeze_time"`
	Type       LeaderboardType `json:"type"`
}

type ContestQuestion

type ContestQuestion struct {
	ID        int       `json:"id"`
	AuthorID  int       `json:"author_id"`
	AskedAt   time.Time `json:"asked_at"`
	ContestID int       `json:"contest_id"`
	Text      string    `json:"text"`

	ResponedAt *time.Time `json:"responded_at"`
	Response   *string    `json:"response"`
}

type ContestRegistration

type ContestRegistration struct {
	CreatedAt time.Time `json:"created_at" db:"created_at"`
	ContestID int       `json:"contest_id" db:"contest_id"`
	UserID    int       `json:"user_id" db:"user_id"`

	IndividualStartTime *time.Time `json:"individual_start" db:"individual_start_at"`
	IndividualEndTime   *time.Time `json:"individual_end" db:"individual_end_at"`

	InvitationID *string `json:"invitation_id" db:"invitation_id"`
}

type ContestType

type ContestType string
const (
	ContestTypeNone     ContestType = ""
	ContestTypeOfficial ContestType = "official"
	ContestTypeVirtual  ContestType = "virtual"
)

type ContestUpdate

type ContestUpdate struct {
	Name *string `json:"name"`

	PublicJoin *bool `json:"public_join"`
	Visible    *bool `json:"visible"`

	Description *string `json:"description"`

	StartTime *time.Time `json:"start_time"`
	EndTime   *time.Time `json:"end_time"`

	MaxSubs *int `json:"max_subs"`

	RegisterDuringContest *bool `json:"register_during_contest"`

	PublicLeaderboard     *bool           `json:"public_leaderboard"`
	LeaderboardStyle      LeaderboardType `json:"leaderboard_style"`
	ICPCSubmissionPenalty *int            `json:"icpc_submission_penalty"`

	LeaderboardAdvancedFilter *bool `json:"leaderboard_advanced_filter"`

	ChangeLeaderboardFreeze bool       `json:"change_leaderboard_freeze"`
	LeaderboardFreeze       *time.Time `json:"leaderboard_freeze"`

	// Normally I'd put a *time.Duration directly here, but schema has a hard time decoding them
	// So the convention is: the unit is an integer number of milliseconds (the resolution set in the DB)
	SubmissionCooldown *int `json:"submission_cooldown"`
	QuestionCooldown   *int `json:"question_cooldown"`

	Type ContestType `json:"type"`

	PerUserTime *int `json:"per_user_time"` // Seconds
}

type Donation

type Donation struct {
	ID        int       `json:"id"`
	DonatedAt time.Time `json:"donated_at"`

	User     *UserBrief `json:"user"`
	Amount   float64    `json:"amount"`
	Currency string     `json:"currency"`

	Source DonationSource `json:"source"`
	Type   DonationType   `json:"type"`

	RealName string `json:"real_name"`

	TransactionID string     `json:"transaction_id"`
	CancelledAt   *time.Time `json:"cancelled_at"`
}

type DonationSource

type DonationSource string
const (
	DonationSourceUnknown DonationSource = ""
	DonationSourceBMAC    DonationSource = "buymeacoffee"
	DonationSourcePaypal  DonationSource = "paypal"
	DonationSourceOther   DonationSource = "other"
)

type DonationType

type DonationType string
const (
	DonationTimeUnknown DonationType = ""
	DonationTypeOneTime DonationType = "onetime"
	DonationTypeMonthly DonationType = "monthly"
	DonationTypeYearly  DonationType = "yearly"
)

type EvalType

type EvalType string
const (
	EvalTypeNone    EvalType = ""
	EvalTypeClassic EvalType = "classic"
	EvalTypeICPC    EvalType = "acm-icpc"
)

type FullSubmission

type FullSubmission struct {
	Submission
	Author   *UserBrief `json:"author"`
	Problem  *Problem   `json:"problem"`
	SubTests []*SubTest `json:"subtests"`

	SubTasks []*SubmissionSubTask `json:"subtasks"`

	// TODO: maybe remove?
	Code []byte `json:"code"`

	// ProblemEditor returns whether the looking user is a problem editor
	ProblemEditor bool `json:"problem_editor"`

	CodeTrulyVisible bool `json:"truly_visible"`
}

type LeaderboardEntry

type LeaderboardEntry struct {
	User *UserBrief `json:"user"`

	// For classic mode
	ProblemScores map[int]decimal.Decimal `json:"scores"`
	TotalScore    decimal.Decimal         `json:"total"`

	// For ICPC mode
	ProblemAttempts map[int]int `json:"attempts"`
	Penalty         int         `json:"penalty"`
	NumSolved       int         `json:"num_solved"`
	// ProblemTimes is expressed as number of minutes since start
	ProblemTimes map[int]float64 `json:"last_times"`

	LastTime   *time.Time `json:"last_time"`
	FreezeTime *time.Time `json:"freeze_time"`
}

TODO: Maybe it would be nicer to coalesce all problem maps in a struct?

type LeaderboardType

type LeaderboardType string
const (
	LeaderboardTypeNone    LeaderboardType = ""
	LeaderboardTypeClassic LeaderboardType = "classic"
	LeaderboardTypeICPC    LeaderboardType = "acm-icpc"
)

type MOSSSubmission added in v0.25.0

type MOSSSubmission struct {
	ID        int       `json:"id" db:"id"`
	CreatedAt time.Time `json:"created_at" db:"created_at"`

	ContestID int `json:"contest_id" db:"contest_id"`
	ProblemID int `json:"problem_id" db:"problem_id"`

	Language string `json:"language" db:"language"`

	URL      string `json:"url" db:"url"`
	SubCount int    `json:"subcount" db:"subcount"`
}

type Mailer

type Mailer interface {
	SendEmail(msg *MailerMessage) error
}

type MailerMessage

type MailerMessage struct {
	To      string
	Subject string
	ReplyTo string

	PlainContent string
	HTMLContent  string
}

type MarkdownRenderer

type MarkdownRenderer interface {
	Render(src []byte, ctx *RenderContext) ([]byte, error)
}

type PreferredTheme

type PreferredTheme string

type Problem

type Problem struct {
	ID        int       `json:"id"`
	CreatedAt time.Time `json:"created_at"`
	Name      string    `json:"name"`
	TestName  string    `json:"test_name"`

	DefaultPoints decimal.Decimal `json:"default_points"`

	Visible      bool `json:"visible"`
	VisibleTests bool `json:"visible_tests"`

	// Limit stuff
	TimeLimit   float64 `json:"time_limit"`
	MemoryLimit int     `json:"memory_limit"`
	SourceSize  int     `json:"source_size"`

	SourceCredits string `json:"source_credits"`

	// Used only for leaderboard scoring right now
	ScoreScale decimal.Decimal `json:"score_scale"`

	// Eval stuff
	ConsoleInput   bool  `json:"console_input"`
	ScorePrecision int32 `json:"score_precision"`

	PublishedAt     *time.Time  `json:"published_at"`
	ScoringStrategy ScoringType `json:"scoring_strategy"`
}

type ProblemChecklist

type ProblemChecklist struct {
	ProblemID        int  `json:"problem_id" db:"problem_id"`
	HasSourceCredits bool `json:"has_source_credits" db:"has_source"`

	NumPDF      int `json:"num_pdf_files" db:"num_pdf"`
	NumMarkdown int `json:"num_md_files" db:"num_md"`

	NumTests    int `json:"num_tests" db:"num_tests"`
	NumSubtasks int `json:"num_subtasks" db:"num_subtasks"`

	NumAuthorTags int `json:"num_author_tags" db:"num_authors"`
	NumOtherTags  int `json:"num_other_tags" db:"num_other_tags"`

	NumSolutions int `json:"num_sols" db:"num_sols"`
}

type ProblemEvalSettings

type ProblemEvalSettings struct {
	// Files to be included during compilation, but not in the compile command
	HeaderFiles []string `json:"header_files"`
	// List of all grader files detected in attachments. Further processing is required to filter by language on evaluation
	GraderFiles []string `json:"grader_files"`
	// If problem has custom checker, this is non-empty
	CheckerName string `json:"has_checker"`
	// If problem has custom checker that is marked as legacy
	LegacyChecker bool `json:"legacy_checker"`

	// Stores the list of languages that are allowed to be submitted based on existing attachments
	LanguageWhitelist []string `json:"lang_whitelist"`
}

type ProblemFilter

type ProblemFilter struct {
	ID           *int    `json:"id"`
	IDs          []int   `json:"ids"`
	ConsoleInput *bool   `json:"console_input"`
	Visible      *bool   `json:"visible"`
	Name         *string `json:"name"`

	FuzzyName *string `json:"name_fuzzy"`

	// DeepListID - the list ID in which to search recursively for problems
	DeepListID *int `json:"deep_list_id"`

	// EditorUserID filter marks if the user is part of the *editors* of the problem
	// Note that it excludes factors like admin or contest editor, it's just the editors in the access section.
	EditorUserID *int `json:"editor_user_id"`

	Tags []*TagGroup `json:"tags"`

	Look             bool       `json:"-"`
	LookEditor       bool       `json:"-"`
	LookFullyVisible bool       `json:"-"`
	LookingUser      *UserBrief `json:"-"`

	// Should be "en" or "ro", if non-nil
	Language *string `json:"lang"`

	// Check problems that have attachment with that ID
	// Currently used for logging statement changes
	AttachmentID *int `json:"-"`

	// Used for getting problems for MOSS
	ContestID *int `json:"-"`

	SolvedBy    *int `json:"solved_by"`
	AttemptedBy *int `json:"attempted_by"`

	// Unassociated filter ensures that all returned problems are not "bound" to a problem list
	Unassociated bool `json:"-"`

	// This is actually not used during filtering in DB, it's used by (*api.API).searchProblems
	ScoreUserID *int `json:"score_user_id"`

	Limit  int `json:"limit"`
	Offset int `json:"offset"`

	Ordering   string `json:"ordering"`
	Descending bool   `json:"descending"`
}

ProblemFilter is the struct with all filterable fields on the problem It also provides a Limit and Offset field, for pagination This list might be expanded as time goes on

type ProblemList

type ProblemList struct {
	ID          int       `json:"id"`
	CreatedAt   time.Time `json:"created_at"`
	AuthorID    int       `json:"author_id"`
	Title       string    `json:"title"`
	Description string    `json:"description"`
	List        []int     `json:"list"`

	// NumProblems holds the number of problems including sublists
	NumProblems int `json:"num_problems"`

	SidebarHidable    bool `json:"sidebar_hidable"`
	FeaturedChecklist bool `json:"featured_checklist"`

	// This is a separate type and not a ProblemList because it might
	// not necessairly be a tree-like structure (ie. it might have cycles)
	SubLists []*ShallowProblemList `json:"sublists"`
}

func (*ProblemList) ProblemIDs

func (p *ProblemList) ProblemIDs() []int

type ProblemListFilter

type ProblemListFilter struct {
	Root              bool  `json:"root"`
	FeaturedChecklist *bool `json:"featured_checklist"`
	// Note that results with ParentID include that parent as well, it should print out the entire tree
	ParentID *int `json:"parent_id"`
}

type ProblemListUpdate

type ProblemListUpdate struct {
	AuthorID    *int    `json:"author_id"`
	Title       *string `json:"title"`
	Description *string `json:"description"`

	SidebarHidable    *bool `json:"sidebar_hidable"`
	FeaturedChecklist *bool `json:"featured_checklist"`
}

type ProblemUpdate

type ProblemUpdate struct {
	Name     *string `json:"name"`
	TestName *string `json:"test_name"`

	DefaultPoints *decimal.Decimal `json:"default_points"`

	ScoreScale *decimal.Decimal `json:"score_scale"`

	TimeLimit   *float64 `json:"time_limit"`
	MemoryLimit *int     `json:"memory_limit"`
	SourceSize  *int     `json:"source_size"`

	SourceCredits *string `json:"source_credits"`

	ConsoleInput *bool `json:"console_input"`
	Visible      *bool `json:"visible"`
	VisibleTests *bool `json:"visible_tests"`

	ScorePrecision  *int32      `json:"score_precision"`
	ScoringStrategy ScoringType `json:"scoring_strategy"`
}

type RenderContext

type RenderContext struct {
	Problem  *Problem
	BlogPost *BlogPost
}

type ScoredProblem

type ScoredProblem struct {
	Problem
	ScoreUserID *int `json:"score_user_id"`

	MaxScore *decimal.Decimal `json:"max_score"`
	// For showing the published/unpublished label on front page
	IsEditor bool `json:"is_editor"`
}

type ScoringType

type ScoringType string
const (
	ScoringTypeNone        ScoringType = ""
	ScoringTypeMaxSub      ScoringType = "max_submission"
	ScoringTypeSumSubtasks ScoringType = "sum_subtasks"
	ScoringTypeICPC        ScoringType = "acm-icpc"
)

type ShallowProblemList

type ShallowProblemList struct {
	ID       int    `json:"id"`
	Title    string `json:"title"`
	AuthorID int    `json:"author_id"`

	SidebarHidable    bool `json:"sidebar_hidable"`
	FeaturedChecklist bool `json:"featured_checklist"`
	// NumProblems holds the number of problems including sublists
	NumProblems int `json:"num_problems"`
}

type StatementVariant

type StatementVariant struct {
	// Language, ie. ro/en
	Language string `json:"lang"`
	// Format, ie. pdf/md/etc.
	Format string `json:"format"`
	// Type, ie. normal/short/llm/etc.
	Type string `json:"type"`
	// Private is true if the attachment for this statement variant is private.
	// it may be private if it's currently being worked on.
	Private bool `json:"public"`
}

func (*StatementVariant) Equals added in v0.25.0

func (sv *StatementVariant) Equals(other *StatementVariant) bool

Used for comparing in templates if the right option is selected.

type Status

type Status string
const (
	StatusNone      Status = ""
	StatusCreating  Status = "creating"
	StatusWaiting   Status = "waiting"
	StatusWorking   Status = "working"
	StatusFinished  Status = "finished"
	StatusReevaling Status = "reevaling"
)

type StatusError

type StatusError struct {
	Code int
	Text string

	WrappedError error
}

func Statusf

func Statusf(status int, format string, args ...any) *StatusError

func WrapError

func WrapError(err error, text string) *StatusError

func (*StatusError) Error

func (s *StatusError) Error() string

func (*StatusError) Is

func (s *StatusError) Is(target error) bool

func (*StatusError) String

func (s *StatusError) String() string

func (*StatusError) Unwrap

func (s *StatusError) Unwrap() error

func (*StatusError) WriteError

func (s *StatusError) WriteError(w http.ResponseWriter)

type SubTask

type SubTask struct {
	ID        int             `json:"id"`
	CreatedAt time.Time       `json:"created_at"`
	ProblemID int             `json:"problem_id"`
	VisibleID int             `json:"visible_id"`
	Score     decimal.Decimal `json:"score"`
	Tests     []int           `json:"tests"`
}

type SubTaskUpdate

type SubTaskUpdate struct {
	VisibleID *int             `json:"visible_id"`
	Score     *decimal.Decimal `json:"score"`
}

type SubTest

type SubTest struct {
	ID           int             `json:"id"`
	CreatedAt    time.Time       `db:"created_at" json:"created_at"`
	Done         bool            `json:"done"`
	Skipped      bool            `json:"skipped"`
	Verdict      string          `json:"verdict"`
	Time         float64         `json:"time"`
	Memory       int             `json:"memory"`
	Percentage   decimal.Decimal `json:"percentage"`
	TestID       *int            `db:"test_id" json:"test_id"`
	SubmissionID int             `db:"submission_id" json:"submission_id"`

	VisibleID int `db:"visible_id" json:"visible_id"`

	Score decimal.Decimal `json:"score"`
}

type SubTestUpdate

type SubTestUpdate struct {
	Memory     *int
	Time       *float64
	Percentage *decimal.Decimal
	Verdict    *string
	Done       *bool
	Skipped    *bool
}

type Submission

type Submission struct {
	ID        int       `json:"id"`
	CreatedAt time.Time `json:"created_at"`
	UserID    int       `json:"user_id"`
	ProblemID int       `json:"problem_id"`
	Language  string    `json:"language"`
	// Code      string    `json:"code,omitempty"`
	CodeSize int    `json:"code_size"`
	Status   Status `json:"status"`

	CompileError   *bool   `json:"compile_error"`
	CompileMessage *string `json:"compile_message,omitempty"`

	ContestID *int `json:"contest_id"`

	MaxTime   float64 `json:"max_time"`
	MaxMemory int     `json:"max_memory"`

	Score          decimal.Decimal `json:"score"`
	ScorePrecision int32           `json:"score_precision"`
	// Used only for leaderboard scoring right now
	ScoreScale decimal.Decimal `json:"score_scale"`

	CompileTime *float64 `json:"compile_time"`

	SubmissionType EvalType `json:"submission_type"`
	ICPCVerdict    *string  `json:"icpc_verdict"`
}

type SubmissionFilter

type SubmissionFilter struct {
	ID        *int  `json:"id"`
	IDs       []int `json:"ids"`
	UserID    *int  `json:"user_id"`
	ProblemID *int  `json:"problem_id"`
	ContestID *int  `json:"contest_id"`

	Status Status `json:"status"`

	// If waiting is true, it returns all submissions with creating/waiting/working status
	// Basically, all unfinished submissions. It's used in the creation of submissions to check limits
	Waiting bool `json:"waiting"`

	Lang         *string `json:"lang"`
	CompileError *bool   `json:"compile_error"`

	Score *decimal.Decimal `json:"score"`

	Look        bool       `json:"-"`
	LookingUser *UserBrief `json:"-"`

	Since *time.Time `json:"-"`

	FromAuthors bool `json:"from_authors"`

	Limit  int `json:"limit"`
	Offset int `json:"offset"`

	Ordering  string `json:"ordering"`
	Ascending bool   `json:"ascending"`
}

type SubmissionPaste

type SubmissionPaste struct {
	ID         string      `json:"id"`
	Submission *Submission `json:"sub"`
	Author     *UserBrief  `json:"author"`
}

type SubmissionSubTask

type SubmissionSubTask struct {
	ID        int       `json:"id"`
	CreatedAt time.Time `json:"created_at"`

	SubmissionID int  `json:"submission_id"`
	UserID       int  `json:"user_id"`
	SubtaskID    *int `json:"subtask_id"`

	ProblemID int  `json:"problem_id"`
	ContestID *int `json:"contest_id"`
	VisibleID int  `json:"visible_id"`

	Score           decimal.Decimal  `json:"score"`
	FinalPercentage *decimal.Decimal `json:"final_percentage,omitempty"`

	ScoreScale *decimal.Decimal `json:"score_scale"`

	ScorePrecision int `json:"score_precision"`

	Subtests []int `json:"subtests"`
}

type SubmissionUpdate

type SubmissionUpdate struct {
	Status Status
	Score  *decimal.Decimal

	CompileError   *bool
	CompileMessage *string
	CompileTime    *float64

	MaxTime   *float64
	MaxMemory *int

	ChangeVerdict bool
	ICPCVerdict   *string
}

type Tag

type Tag struct {
	ID   int     `json:"id"`
	Name string  `json:"name"`
	Type TagType `json:"type"`
}

type TagGroup

type TagGroup struct {
	// Negate instructs wether the filtered problem should have
	// or NOT have the corresponding tags in order for it to match
	Negate bool `json:"negate"`
	// TagIDs represents the set of tags which, when intersected with
	// the problem's tag set must be non-empty in order to get a match
	TagIDs []int `json:"tag_ids"`
}

Should be used for problem filtering

type TagType

type TagType string
const (
	TagTypeNone    TagType = ""
	TagTypeAuthor  TagType = "author"
	TagTypeContest TagType = "contest"
	TagTypeMethod  TagType = "method"
	TagTypeOther   TagType = "other"
)

type Test

type Test struct {
	ID        int             `json:"id"`
	CreatedAt time.Time       `db:"created_at" json:"created_at"`
	Score     decimal.Decimal `json:"score"`
	ProblemID int             `db:"problem_id" json:"problem_id"`
	VisibleID int             `db:"visible_id" json:"visible_id"`
}

type TestUpdate

type TestUpdate struct {
	Score     *decimal.Decimal `json:"score"`
	VisibleID *int             `json:"visible_id"`
}

type Translation

type Translation map[string]string

type Translations

type Translations map[string]Translation

type UserBrief

type UserBrief struct {
	ID       int    `json:"id"`
	Name     string `json:"name"`
	Admin    bool   `json:"admin"`
	Proposer bool   `json:"proposer"`

	DisplayName string `json:"display_name"`

	Generated bool `json:"generated"`
}

func (*UserBrief) IsAdmin

func (u *UserBrief) IsAdmin() bool

func (*UserBrief) IsAuthed

func (u *UserBrief) IsAuthed() bool

func (*UserBrief) IsProposer

func (u *UserBrief) IsProposer() bool

type UserFilter

type UserFilter struct {
	ID  *int  `json:"id"`
	IDs []int `json:"ids"`

	// Name is case insensitive
	Name  *string `json:"name"`
	Email *string `json:"email"`

	// For user filtering
	FuzzyName *string `json:"name_fuzzy"`

	Admin    *bool `json:"admin"`
	Proposer *bool `json:"proposer"`

	// For registrations
	ContestID *int `json:"contest_id"`

	// For filtering in leaderboards
	Generated *bool `json:"generated"`

	// For session recognition
	SessionID *string `json:"session_id"`

	Limit  int `json:"limit"`
	Offset int `json:"offset"`
}

UserFilter is the struct with all filterable fields on the user It also provides a Limit and Offset field, for pagination

type UserFull

type UserFull struct {
	UserBrief
	Bio               string         `json:"bio,omitempty"`
	Email             string         `json:"email,omitempty"`
	VerifiedEmail     bool           `json:"verified_email"`
	PreferredLanguage string         `json:"preferred_language"`
	PreferredTheme    PreferredTheme `json:"preferred_theme"`
	EmailVerifResent  time.Time      `json:"-"`
	CreatedAt         time.Time      `json:"created_at"`
	// Generated         bool           `json:"generated"`
	LockedLogin      bool `json:"locked_login"`
	NameChangeForced bool `json:"name_change_forced"`
}

func (*UserFull) Brief

func (uf *UserFull) Brief() *UserBrief

type UserFullUpdate

type UserFullUpdate struct {
	UserUpdate

	Name *string `json:"name"`

	Email *string `json:"email"`

	Admin    *bool `json:"admin"`
	Proposer *bool `json:"proposer"`

	LockedLogin        *bool `json:"locked_login"`
	NameChangeRequired *bool `json:"name_change_required"`

	VerifiedEmail    *bool      `json:"verified_email"`
	EmailVerifSentAt *time.Time `json:"-"`
}

UserFullUpdate is the struct with all updatable fields on the user. Internal use only

type UserUpdate

type UserUpdate struct {
	DisplayName *string `json:"display_name"`

	Bio *string `json:"bio"`

	PreferredLanguage string         `json:"-"`
	PreferredTheme    PreferredTheme `json:"-"`
}

UserUpdate is the struct with updatable fields that can be easily changed. Stuff like admin and proposer should be updated through their dedicated SudoAPI methods

type UsernameChange

type UsernameChange struct {
	UserID    int       `json:"user_id" db:"user_id"`
	Name      string    `json:"name" db:"name"`
	ChangedAt time.Time `json:"changed_at" db:"changed_at"`
}

Directories

Path Synopsis
archive
cmd
kn
contrib
box
integrations
llm
internal
scripts
mdrenderer/knkatex
Code in katex.go has been mostly derived from [goldmark-mathjax](https://github.com/litao91/goldmark-mathjax).
Code in katex.go has been mostly derived from [goldmark-mathjax](https://github.com/litao91/goldmark-mathjax).
Package web is the client-side router that manages the website If the `server` package interacts with the DB, the `web` package interacts with the user
Package web is the client-side router that manages the website If the `server` package interacts with the DB, the `web` package interacts with the user

Jump to

Keyboard shortcuts

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