122 lines
2.2 KiB
Go
122 lines
2.2 KiB
Go
|
// Package metadata handles API request that search for metadata regarding osu!
|
||
|
// beatmaps.
|
||
|
package metadata
|
||
|
|
||
|
import (
|
||
|
"strconv"
|
||
|
"strings"
|
||
|
|
||
|
"github.com/osuripple/cheesegull/api"
|
||
|
"github.com/osuripple/cheesegull/models"
|
||
|
)
|
||
|
|
||
|
// Beatmap handles requests to retrieve single beatmaps.
|
||
|
func Beatmap(c *api.Context) {
|
||
|
id, _ := strconv.Atoi(strings.TrimSuffix(c.Param("id"), ".json"))
|
||
|
if id == 0 {
|
||
|
c.WriteJSON(404, nil)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
bms, err := models.FetchBeatmaps(c.DB, id)
|
||
|
if err != nil {
|
||
|
c.Err(err)
|
||
|
c.WriteJSON(500, nil)
|
||
|
return
|
||
|
}
|
||
|
if len(bms) == 0 {
|
||
|
c.WriteJSON(404, nil)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
c.WriteJSON(200, bms[0])
|
||
|
}
|
||
|
|
||
|
// Set handles requests to retrieve single beatmap sets.
|
||
|
func Set(c *api.Context) {
|
||
|
id, _ := strconv.Atoi(strings.TrimSuffix(c.Param("id"), ".json"))
|
||
|
if id == 0 {
|
||
|
c.WriteJSON(404, nil)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
set, err := models.FetchSet(c.DB, id, true)
|
||
|
if err != nil {
|
||
|
c.Err(err)
|
||
|
c.WriteJSON(500, nil)
|
||
|
return
|
||
|
}
|
||
|
if set == nil {
|
||
|
c.WriteJSON(404, nil)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
c.WriteJSON(200, set)
|
||
|
}
|
||
|
|
||
|
func mustInt(s string) int {
|
||
|
i, _ := strconv.Atoi(s)
|
||
|
return i
|
||
|
}
|
||
|
|
||
|
func mustPositive(i int) int {
|
||
|
if i < 0 {
|
||
|
return 0
|
||
|
}
|
||
|
return i
|
||
|
}
|
||
|
|
||
|
func intWithBounds(i, min, max, def int) int {
|
||
|
if i == 0 {
|
||
|
return def
|
||
|
}
|
||
|
if i < min {
|
||
|
return min
|
||
|
}
|
||
|
if i > max {
|
||
|
return max
|
||
|
}
|
||
|
return i
|
||
|
}
|
||
|
|
||
|
func sIntWithBounds(strs []string, min, max int) []int {
|
||
|
sInt := make([]int, 0, len(strs))
|
||
|
for _, s := range strs {
|
||
|
i, err := strconv.Atoi(s)
|
||
|
if err != nil || i < min || i > max {
|
||
|
continue
|
||
|
}
|
||
|
sInt = append(sInt, i)
|
||
|
}
|
||
|
return sInt
|
||
|
}
|
||
|
|
||
|
// Search does a search on the sets available in the database.
|
||
|
func Search(c *api.Context) {
|
||
|
query := c.Request.URL.Query()
|
||
|
sets, err := models.SearchSets(c.DB, c.SearchDB, models.SearchOptions{
|
||
|
Status: sIntWithBounds(query["status"], -2, 4),
|
||
|
Query: query.Get("query"),
|
||
|
Mode: sIntWithBounds(query["mode"], 0, 3),
|
||
|
|
||
|
Amount: intWithBounds(mustInt(query.Get("amount")), 1, 100, 50),
|
||
|
Offset: mustPositive(mustInt(query.Get("offset"))),
|
||
|
})
|
||
|
if err != nil {
|
||
|
c.Err(err)
|
||
|
c.WriteJSON(500, nil)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
c.WriteJSON(200, sets)
|
||
|
}
|
||
|
|
||
|
func init() {
|
||
|
api.GET("/api/b/:id", Beatmap)
|
||
|
api.GET("/b/:id", Beatmap)
|
||
|
api.GET("/api/s/:id", Set)
|
||
|
api.GET("/s/:id", Set)
|
||
|
|
||
|
api.GET("/api/search", Search)
|
||
|
}
|