Documentation
¶
Index ¶
- Constants
- Variables
- func CheckPwdHash(password, hash string) bool
- func GetText(lang, line string, args ...any) string
- func GetZapCore(debug bool, color bool, out io.Writer) zapcore.Core
- func HashPassword(password string) (string, error)
- func MakeSlug(org string) string
- func RandomString(size int) string
- func StatusData(w http.ResponseWriter, status string, retData any, statusCode int)
- func TranslationKeyExists(line string) bool
- func ValidTagType(t TagType) bool
- type Attachment
- type AttachmentFilter
- type AttachmentUpdate
- type AuditLog
- type BlogPost
- type BlogPostFilter
- type BlogPostUpdate
- type Contest
- type ContestAnnouncement
- type ContestFilter
- type ContestInvitation
- type ContestLeaderboard
- type ContestQuestion
- type ContestRegistration
- type ContestType
- type ContestUpdate
- type DataStore
- type Donation
- type DonationSource
- type DonationType
- type EvalType
- type FullSubmission
- type GraderStore
- type LeaderboardEntry
- type LeaderboardType
- type Mailer
- type MailerMessage
- type MarkdownRenderer
- type PreferredTheme
- type Problem
- type ProblemChecklist
- type ProblemEvalSettings
- type ProblemFilter
- type ProblemList
- type ProblemListFilter
- type ProblemListUpdate
- type ProblemUpdate
- type RenderContext
- type ScoredProblem
- type ScoringType
- type ShallowProblemList
- type StatementVariant
- type Status
- type StatusError
- type SubTask
- type SubTaskUpdate
- type SubTest
- type SubTestUpdate
- type Submission
- type SubmissionFilter
- type SubmissionPaste
- type SubmissionSubTask
- type SubmissionUpdate
- type Tag
- type TagGroup
- type TagType
- type Test
- type TestUpdate
- type Translation
- type Translations
- type UserBrief
- type UserFilter
- type UserFull
- type UserFullUpdate
- type UserUpdate
- type UsernameChange
Constants ¶
const ( PreferredThemeNone = "" PreferredThemeLight = "light" PreferredThemeDark = "dark" )
const (
DefaultSourceSize = 30000
)
const MaxScoreRoundingPlaces = 4
const Version = "v0.24.0"
Variables ¶
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") )
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") )
var (
ErrAttachmentExists = Statusf(400, "Attachment with that name already exists!")
)
Functions ¶
func CheckPwdHash ¶
func HashPassword ¶
func RandomString ¶
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 ValidTagType ¶
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 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 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"`
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"`
}
type ContestAnnouncement ¶
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 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 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"`
ChangeLeaderboardFreeze bool `json:"change_leaderboard_freeze"`
LeaderboardFreeze *time.Time `json:"leaderboard_freeze"`
Type ContestType `json:"type"`
PerUserTime *int `json:"per_user_time"` // Seconds
}
type DataStore ¶
type DataStore interface {
GraderStore
HasAttachmentRender(attID int, renderType string) bool
GetAttachmentRender(attID int, renderType string) (io.ReadCloser, error)
DelAttachmentRender(attID int, renderType string) error
// Like DelAttachmentRender but removes all renderTypes indiscriminately
DelAttachmentRenders(attID int) error
SaveAttachmentRender(attID int, renderType string, data []byte) error
InvalidateAllAttachments() error
SaveAvatar(email string, size int, r io.Reader) error
// valid is true only if maxLastMod is greater than the saved value and if the avatar is saved
GetAvatar(email string, size int, maxLastMod time.Time) (data io.ReadSeeker, lastMod time.Time, valid bool, err error)
PurgeAvatarCache() 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.ReadCloser, error)
TestOutput(testID int) (io.ReadCloser, 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.ReadCloser, 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]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 Mailer ¶
type Mailer interface {
SendEmail(msg *MailerMessage) error
}
type MailerMessage ¶
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:"-"`
// 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:"-"`
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 ProblemListUpdate ¶
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 ScoredProblem ¶
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"`
// 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 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 SubTaskUpdate ¶
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"`
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 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"`
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"`
ScorePrecision int `json:"score_precision"`
Subtests []int `json:"subtests"`
}
type SubmissionUpdate ¶
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 TestUpdate ¶
type Translation ¶
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"`
}
func (*UserBrief) IsProposer ¶
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"`
}
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
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
archive
|
|
|
cmd
|
|
|
kn
command
|
|
|
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 |
