package utils import ( "context" "encoding/json" "fmt" "log" "net/http" "time" "omctf.ru/block-game-backend/codegen/ent/level" "omctf.ru/block-game-backend/codegen/ent/predicate" "omctf.ru/block-game-backend/codegen/ent/user" "omctf.ru/block-game-backend/db" ) func BailInternalServerError(w http.ResponseWriter, err error) { http.Error(w, "Unexpected error", http.StatusInternalServerError) log.Printf("Unexpected error occured: %v\n", err) } func RespondWithJSON(w http.ResponseWriter, o any) { data, err := json.Marshal(o) if err != nil { BailInternalServerError(w, err) return } w.Header().Set("Content-Type", "application/json") w.Write(data) } func GetJSONBody[T any](r *http.Request) (*T, error) { var req T err := json.NewDecoder(r.Body).Decode(&req) if err != nil { return nil, fmt.Errorf("invalid request body: %w", err) } return &req, nil } func MustMarshal(value any) json.RawMessage { data, err := json.Marshal(value) if err != nil { log.Panicf("Can't marshal value %v: %s", value, err) } return data } func LevelAccessibleBy(userId int) predicate.Level { return level.Or( // one of level.HasOwnerWith(user.ID(userId)), // user owns the level level.HasInvitedPlayersWith(user.ID(userId)), // or user is invited to the level level.VisibilityEQ(level.VisibilityPublic), // or it's public ) } const ( CleanUpDelay = time.Hour * 1 ) func OccasionallyCleanUp() { ticker := time.NewTicker(CleanUpDelay / 4) for range ticker.C { cnt, err := db.Client.Level.Delete().Where( level.CreatedAtLT(time.Now().Add(-CleanUpDelay)), ).Exec(context.Background()) if err != nil { log.Printf("Error during levels clean up: %s", err) } log.Printf("Cleaned up %d levels", cnt) } }