kilonova

package module
v0.0.0-...-5733806 Latest Latest
Warning

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

Go to latest
Published: Oct 10, 2023 License: AGPL-3.0 Imports: 16 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 (
	DefaultSourceSize = 30000
)
View Source
const MaxScoreRoundingPlaces = 4
View Source
const Version = "v0.22.0"

Variables

View Source
var (
	ErrDirectory    = Statusf(400, "File is actually directory")
	ErrNotDirectory = Statusf(400, "Not a directory")
	ErrNotEmpty     = Statusf(400, "Directory you are trying to delete is not empty")
	ErrNoDirInPath  = Statusf(400, "Trying to save in a directory which is actually a file")
	ErrNotExist     = Statusf(404, "Error doesn't exist")
)
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")
)
View Source
var (
	ErrAttachmentExists = Statusf(400, "Attachment with that name already exists!")
)

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 RandomString

func RandomString(size int) string

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

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"`

	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"`

	// 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 ContestLeaderboard

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

	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"`
}

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"`

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

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

type DataStore

type DataStore interface {
	GraderStore

	HasAttachmentRender(attID int) bool
	GetAttachmentRender(attID int) (io.ReadSeekCloser, error)
	DelAttachmentRender(attID int) error
	SaveAttachmentRender(attID int, data []byte) error

	InvalidateAllAttachments() error
}

DataStore represents an interface for the Data Storage Manager

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 FullSubmission

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

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

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

	CodeTrulyVisible bool `json:"truly_visible"`
}

type GraderStore

type GraderStore interface {
	TestInput(testID int) (io.ReadSeekCloser, error)
	TestOutput(testID int) (io.ReadSeekCloser, error)

	PurgeTestData(testID int) error

	SaveTestInput(testID int, input io.Reader) error
	SaveTestOutput(testID int, output io.Reader) error

	SubtestWriter(subtest int) (io.WriteCloser, error)
	SubtestReader(subtest int) (io.ReadSeekCloser, error)
}

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]int `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 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"`

	// 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 {
	// If header/grader files are found, this is turned on to True
	OnlyCPP bool `json:"only_cpp"`
	// Files to be included during compilation
	HeaderFiles []string `json:"header_files"`
	// Files to be included in both the
	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"`
	// If problem has ".output_only" attachment, show only outputOnly language as option
	OutputOnly bool `bool:"output_only"`
}

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:"-"`
	LookingUser *UserBrief `json:"-"`

	// Check problems that have attachment with that ID
	// Currently used for logging statement changes
	AttachmentID *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:"-"`

	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"`

	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"
)

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"`
	// 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"`
}

type Status

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

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"`
	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"`
	UserID       int             `db:"user_id" json:"user_id"`
	SubmissionID int             `db:"submission_id" json:"submission_id"`

	ContestID *int `db:"contest_id" json:"contest_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
}

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"`
}

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"`
	Lang         *string `json:"lang"`
	CompileError *bool   `json:"compile_error"`

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

	Look        bool       `json:"-"`
	LookingUser *UserBrief `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"`

	ScorePrecision int `json:"score_precision"`

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

type SubmissionUpdate

type SubmissionUpdate struct {
	Status Status
	Score  *decimal.Decimal

	CompileError   *bool
	CompileMessage *string

	MaxTime   *float64
	MaxMemory *int
}

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"`
}

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 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 {
	//Name    *string `json:"name"`
	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
internal
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