diff --git a/huso.go b/huso.go index a5fb4ba..4645fef 100644 --- a/huso.go +++ b/huso.go @@ -21,6 +21,7 @@ const ( userApiJikan = "users/" userApiMal = "users/" animeApiMal = "anime/" + searchApiMal = "anime?q=" malApiStatusP = "plan_to_watch" malApiStatusW = "watching" malApiStatusC = "completed" @@ -40,6 +41,7 @@ var ( animeCache *bigcache.BigCache seasoncache *bigcache.BigCache userCache *bigcache.BigCache + searchCache *bigcache.BigCache db *nutsdb.DB ) @@ -69,6 +71,11 @@ func main() { log.Fatal(err) } defer userCache.Close() + searchCache, err = bigcache.NewBigCache(bigcache.DefaultConfig(7 * time.Minute)) + if err != nil { + log.Fatal(err) + } + defer searchCache.Close() nutsOpt := nutsdb.DefaultOptions nutsOpt.Dir = "nuts" diff --git a/klotz.go b/klotz.go index 80a71e4..9932991 100644 --- a/klotz.go +++ b/klotz.go @@ -130,14 +130,7 @@ type AnimeDetailMal struct { type AnimeListMal struct { Data []struct { - Node struct { - ID int64 `json:"id"` - Title string `json:"title"` - MainPicture struct { - Medium string `json:"medium"` - Large string `json:"large"` - } `json:"main_picture"` - } `json:"node"` + Node AnimeDetailMal `json:"node"` } `json:"data"` Paging struct { Next string `json:"next"` @@ -167,14 +160,7 @@ type UserJikan struct { type SeasonMal struct { Data []struct { - Node struct { - ID int64 `json:"id"` - Title string `json:"title"` - MainPicture struct { - Medium string `json:"medium"` - Large string `json:"large"` - } `json:"main_picture"` - } `json:"node"` + Node AnimeDetailMal `json:"node"` } `json:"data"` Paging struct { Next string `json:"next"` diff --git a/knecht.go b/knecht.go index c8c8534..79b88da 100644 --- a/knecht.go +++ b/knecht.go @@ -12,6 +12,36 @@ import ( "github.com/valyala/fasthttp" ) +func SearchAnime(query string) ([]Anime, []byte, error) { + var animes []Anime + data, err := searchCache.Get(query) + if err != nil { + err = nil + dataMal, err := GetDataMal(searchApiMal + query + "&fields=id,title,main_picture,alternative_titles,start_date,end_date,synopsis,mean,rank,popularity,num_list_users,num_scoring_users,nsfw,media_type,status,genres,my_list_status,num_episodes,start_season,broadcast,source,average_episode_duration,rating,studios&limit=100") + if err != nil { + return nil, nil, err + } + var animeList AnimeListMal + animes = make([]Anime, 0) + err = json.Unmarshal(dataMal, &animeList) + if err != nil { + return nil, nil, err + } + // convert to anime + for _, a := range animeList.Data { + animes = append(animes, MalConvert(&a.Node)) + } + data, err = json.Marshal(animes) + if err != nil { + return animes, data, err + } + searchCache.Set(query, data) + } else { + err = json.Unmarshal(data, &animes) + } + return animes, data, err +} + func GetAnimeDetailData(animeId int64) (*Anime, []byte, error) { var anime Anime key := strconv.FormatInt(animeId, 10) diff --git a/ober.go b/ober.go index 21a5502..8b0cc90 100644 --- a/ober.go +++ b/ober.go @@ -17,6 +17,7 @@ func RunWebserv() { r.GET("/", Headers(Start)) r.GET("/api/season", Headers(Season)) r.GET("/api/anime/{id}", Headers(AnimeGet)) + r.GET("/api/animesearch/", Headers(AnimeSearchGet)) r.GET("/api/user/{user?}", Headers(UserGet)) r.GET("/api/watch/{user?}", Headers(WatchGet)) r.GET("/api/watchext/{user?}", Headers(WatchExtendedGet)) @@ -96,6 +97,28 @@ func AnimeGet(ctx *fasthttp.RequestCtx) { ctx.SetStatusCode(fasthttp.StatusOK) } +func AnimeSearchGet(ctx *fasthttp.RequestCtx) { + if !ctx.QueryArgs().Has("q") || string(ctx.QueryArgs().Peek("q")) == "" { + ctx.SetStatusCode(fasthttp.StatusBadRequest) + return + } + query := string(ctx.QueryArgs().Peek("q")) + // Search with query + _, bytes, err := SearchAnime(query) + if err != nil { + addErrorToCtx(ctx, err) + return + } + _, err = ctx.Write(bytes) + if err != nil { + addErrorToCtx(ctx, err) + return + } + + ctx.SetContentType("application/json; charset=utf-8") + ctx.SetStatusCode(fasthttp.StatusOK) +} + func UserGet(ctx *fasthttp.RequestCtx) { usrVal := ctx.UserValue("user") users := make([]User, 0)