aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVidhu Kant Sharma <vidhukant@vidhukant.com>2023-08-15 13:37:22 +0530
committerVidhu Kant Sharma <vidhukant@vidhukant.com>2023-08-15 13:37:22 +0530
commitd0d0d0cdc4218f1f944481a5116c74d81682deff (patch)
tree9cca99607126273d317ad9bae0b66c6248f07035
parent266af04ade2dd1617bb27079779bdb81d6f18ee0 (diff)
added validators for read-only endpoints
-rw-r--r--anime.go32
-rw-r--r--errors.go16
-rw-r--r--manga.go18
-rw-r--r--mg.go70
-rw-r--r--params.go8
-rw-r--r--validators.go276
6 files changed, 407 insertions, 13 deletions
diff --git a/anime.go b/anime.go
index 4246cc5..d73920c 100644
--- a/anime.go
+++ b/anime.go
@@ -22,7 +22,11 @@ import "encoding/json"
const ANIME_BASE_URL string = BASE_URL + "/anime"
func (c Client) SearchAnime(animes *[]Anime, params *SearchParams) error {
- // TODO: validate params
+ err := validateAnimeSearchParams(params)
+ if err != nil {
+ return err
+ }
+
var res struct {
Data []struct {
Anime Anime `json:"node"`
@@ -43,7 +47,11 @@ func (c Client) SearchAnime(animes *[]Anime, params *SearchParams) error {
}
func (c Client) GetAnimeById(anime *Anime, id int, fields []string) error {
- // TODO: validate params
+ err := validateAnimeFields(&fields)
+ if err != nil {
+ return err
+ }
+
body, err := c.get(ANIME_BASE_URL + getIdQuery(id, fields))
if err != nil {
return err
@@ -54,7 +62,11 @@ func (c Client) GetAnimeById(anime *Anime, id int, fields []string) error {
}
func (c Client) GetAnimeRanking(animes *[]RankedAnime, params *RankingParams) error {
- // TODO: validate params
+ err := validateAnimeRankingParams(params)
+ if err != nil {
+ return err
+ }
+
body, err := c.get(ANIME_BASE_URL + getRankingQuery(params))
if err != nil {
return err
@@ -79,7 +91,11 @@ func (c Client) GetAnimeRanking(animes *[]RankedAnime, params *RankingParams) er
}
func (c Client) GetSeasonalAnime(animes *[]Anime, params *SeasonalParams) error {
- // TODO: validate params
+ err := validateSeasonalParams(params)
+ if err != nil {
+ return err
+ }
+
body, err := c.get(ANIME_BASE_URL + getSeasonalQuery(params))
if err != nil {
return err
@@ -100,9 +116,13 @@ func (c Client) GetSeasonalAnime(animes *[]Anime, params *SeasonalParams) error
return nil
}
+// TODO: only allow MainAuth not ClientAuth
func (c Client) GetSuggestedAnime(animes *[]Anime, params *SuggestedParams) error {
- // TODO: validate params
- // TODO: only allow MainAuth not ClientAuth
+ err := validateSuggestedParams(params)
+ if err != nil {
+ return err
+ }
+
body, err := c.get(ANIME_BASE_URL + getSuggestedQuery(params))
if err != nil {
return err
diff --git a/errors.go b/errors.go
index 206585b..d2b2828 100644
--- a/errors.go
+++ b/errors.go
@@ -16,3 +16,19 @@
*/
package mg
+
+import "errors"
+
+var (
+ ErrLimitOutOfRange = errors.New("mg: invalid limit (out of range)")
+ ErrInvalidField = errors.New("mg: invalid field passed")
+ ErrInvalidRankingType = errors.New("mg: invalid ranking type")
+ ErrInvalidSeason = errors.New("mg: invalid season")
+ ErrInvalidSort = errors.New("mg: invalid sort")
+ ErrInvalidStatus = errors.New("mg: invalid status")
+ ErrInvalidScore = errors.New("mg: invalid score")
+ ErrInvalidPriority = errors.New("mg: invalid priority")
+ ErrInvalidRewatchValue = errors.New("mg: invalid rewatch value")
+ ErrInvalidRereadValue = errors.New("mg: invalid reread value")
+ ErrEmptySearchString = errors.New("mg: invalid search string (empty string)")
+)
diff --git a/manga.go b/manga.go
index 6b5ff3b..626ef94 100644
--- a/manga.go
+++ b/manga.go
@@ -22,7 +22,11 @@ import "encoding/json"
const MANGA_BASE_URL string = BASE_URL + "/manga"
func (c Client) SearchManga(mangas *[]Manga, params *SearchParams) error {
- // TODO: validate params
+ err := validateMangaSearchParams(params)
+ if err != nil {
+ return err
+ }
+
var res struct {
Data []struct {
Manga Manga `json:"node"`
@@ -43,7 +47,11 @@ func (c Client) SearchManga(mangas *[]Manga, params *SearchParams) error {
}
func (c Client) GetMangaById(manga *Manga, id int, fields []string) error {
- // TODO: validate params
+ err := validateMangaFields(&fields)
+ if err != nil {
+ return err
+ }
+
body, err := c.get(ANIME_BASE_URL + getIdQuery(id, fields))
if err != nil {
return err
@@ -54,7 +62,11 @@ func (c Client) GetMangaById(manga *Manga, id int, fields []string) error {
}
func (c Client) GetMangaRanking(mangas *[]RankedManga, params *RankingParams) error {
- // TODO: validate params
+ err := validateMangaRankingParams(params)
+ if err != nil {
+ return err
+ }
+
body, err := c.get(MANGA_BASE_URL + getRankingQuery(params))
if err != nil {
return err
diff --git a/mg.go b/mg.go
index 05eb640..7b7cea5 100644
--- a/mg.go
+++ b/mg.go
@@ -41,3 +41,73 @@ const (
Tags = "tags"
Comments = "comments"
)
+
+// for getting ranking list
+const (
+ // for anime only
+ RankingTypeAiring = "airing"
+ RankingTypeUpcoming = "upcoming"
+ RankingTypeTV = "tv"
+ RankingTypeOVA = "ova"
+ RankingTypeMovie = "movie"
+ RankingTypeSpecial = "special"
+
+ // for manga only
+ RankingTypeManga = "manga"
+ RankingTypeNovel = "novels"
+ RankingTypeOneShot = "oneshots"
+ RankingTypeDoujin = "doujin"
+ RankingTypeManhwa = "manhwa"
+ RankingTypeManhua = "manhua"
+
+ // for both
+ RankingTypeAll = "all"
+ RankingTypeByPopularity = "bypopularity"
+ RankingTypeFavorite = "favorite"
+)
+
+// for anime/manga list sort
+const (
+ // for anime only
+ SortByAnimeTitle = "anime_title"
+ SortByAnimeStartDate = "anime_start_date"
+ SortByAnimeId = "anime_id"
+
+ // for manga only
+ SortByMangaTitle = "manga_title"
+ SortByMangaStartDate = "manga_start_date"
+ SortByMangaId = "manga_id"
+
+ // for both
+ SortByListScore = "list_score"
+ SortByListUpdatedAt = "list_updated_at"
+)
+
+// for anime/manga list status
+const (
+ // for anime only
+ ListStatusWatching = "watching"
+ ListStatusPTW = "plan_to_watch"
+
+ // for manga only
+ ListStatusReading = "watching"
+ ListStatusPTR = "plan_to_read"
+
+ // for both
+ ListStatusCompleted = "completed"
+ ListStatusOnHold = "on_hold"
+ ListStatusDropped = "dropped"
+)
+
+// for anime seasons
+const (
+ // season names
+ SeasonWinter = "winter"
+ SeasonSpring = "spring"
+ SeasonSummer = "summer"
+ SeasonFall = "fall"
+
+ // sorting
+ SeasonSortByAnimeScore = "anime_score"
+ SeasonSortByNumListUsers = "num_list_users"
+)
diff --git a/params.go b/params.go
index 4fa1406..d29c2f4 100644
--- a/params.go
+++ b/params.go
@@ -75,7 +75,7 @@ func SearchParamsNew() *SearchParams {
func RankingParamsNew() *RankingParams {
return &RankingParams {
- RankingType: "",
+ RankingType: RankingTypeAll,
Limit: 100,
Offset: 0,
NSFW: false,
@@ -87,7 +87,7 @@ func SeasonalParamsNew() *SeasonalParams {
return &SeasonalParams {
Year: "",
Season: "",
- Sort: "",
+ Sort: SeasonSortByAnimeScore,
Limit: 100,
Offset: 0,
NSFW: false,
@@ -106,9 +106,9 @@ func SuggestedParamsNew() *SuggestedParams {
func ListParamsNew() *ListParams {
return &ListParams {
- Username: "",
+ Username: "@me",
Status: "",
- Sort: "",
+ Sort: "list_score",
Limit: 100,
Offset: 0,
NSFW: false,
diff --git a/validators.go b/validators.go
index 206585b..2dafaad 100644
--- a/validators.go
+++ b/validators.go
@@ -16,3 +16,279 @@
*/
package mg
+
+import (
+ "strings"
+ "slices"
+)
+
+func validateAnimeFields(fields *[]string) error {
+ // if no fields given, set all
+ if cap(*fields) == 0 {
+ *fields = DefaultAnimeFields
+ return nil
+ }
+
+ // check if given fields exist in DefaultAnimeFields
+ for _, f := range *fields {
+ if !slices.Contains(DefaultAnimeFields, f) {
+ return ErrInvalidField
+ }
+ }
+
+ return nil
+}
+
+func validateAnimeRankingType(t string) error {
+ if !slices.Contains([]string{
+ RankingTypeAll,
+ RankingTypeByPopularity,
+ RankingTypeFavorite,
+ RankingTypeAiring,
+ RankingTypeUpcoming,
+ RankingTypeTV,
+ RankingTypeOVA,
+ RankingTypeMovie,
+ RankingTypeSpecial,
+ }, t) {
+ return ErrInvalidRankingType
+ }
+
+ return nil
+}
+
+func validateAnimeListSort(s string) error {
+ if !slices.Contains([]string{
+ SortByListScore,
+ SortByListUpdatedAt,
+ SortByAnimeTitle,
+ SortByAnimeStartDate,
+ SortByAnimeId,
+ }, s) {
+ return ErrInvalidSort
+ }
+
+ return nil
+}
+
+func validateAnimeListStatus(s string) error {
+ if !slices.Contains([]string{
+ ListStatusCompleted,
+ ListStatusOnHold,
+ ListStatusDropped,
+ ListStatusWatching,
+ ListStatusPTW,
+ }, s) {
+ return ErrInvalidStatus
+ }
+
+ return nil
+}
+
+func validateAnimeSeason(s string) error {
+ if !slices.Contains([]string{
+ SeasonWinter,
+ SeasonSpring,
+ SeasonSummer,
+ SeasonFall,
+ }, s) {
+ return ErrInvalidSeason
+ }
+
+ return nil
+}
+
+func validateAnimeSeasonSort(s string) error {
+ if !slices.Contains([]string{
+ SeasonSortByAnimeScore,
+ SeasonSortByNumListUsers,
+ }, s) {
+ return ErrInvalidSort
+ }
+
+ return nil
+}
+
+func validateMangaFields(fields *[]string) error {
+ // if no fields given, set all
+ if cap(*fields) == 0 {
+ *fields = DefaultMangaFields
+ return nil
+ }
+
+ // check if given fields exist in DefaultAnimeFields
+ for _, f := range *fields {
+ if !slices.Contains(DefaultMangaFields, f) {
+ return ErrInvalidField
+ }
+ }
+
+ return nil
+}
+
+func validateMangaRankingType(t string) error {
+ if !slices.Contains([]string{
+ RankingTypeAll,
+ RankingTypeByPopularity,
+ RankingTypeFavorite,
+ RankingTypeManga,
+ RankingTypeNovel,
+ RankingTypeOneShot,
+ RankingTypeDoujin,
+ RankingTypeManhwa,
+ RankingTypeManhua,
+ }, t) {
+ return ErrInvalidRankingType
+ }
+
+ return nil
+}
+
+func validateMangaListSort(s string) error {
+ if !slices.Contains([]string{
+ SortByListScore,
+ SortByListUpdatedAt,
+ SortByMangaTitle,
+ SortByMangaStartDate,
+ SortByMangaId,
+ }, s) {
+ return ErrInvalidSort
+ }
+
+ return nil
+}
+
+func validateMangaListStatus(s string) error {
+ if !slices.Contains([]string{
+ ListStatusCompleted,
+ ListStatusOnHold,
+ ListStatusDropped,
+ ListStatusReading,
+ ListStatusPTR,
+ }, s) {
+ return ErrInvalidStatus
+ }
+
+ return nil
+}
+
+func validateScore(score int) error {
+ if score >= 0 && score <= 10 {
+ return nil
+ }
+
+ return ErrInvalidScore
+}
+
+func validatePriority(priority int) error {
+ if priority >= 0 && priority <= 2 {
+ return nil
+ }
+
+ return ErrInvalidPriority
+}
+
+func validateRewatchValue(val int) error {
+ if val >= 0 && val <= 5 {
+ return nil
+ }
+
+ return ErrInvalidRewatchValue
+}
+
+func validateRereadValue(val int) error {
+ if val >= 0 && val <= 5 {
+ return nil
+ }
+
+ return ErrInvalidRereadValue
+}
+
+func validateAnimeSearchParams(params *SearchParams) error {
+ if strings.TrimSpace(params.SearchString) == "" {
+ return ErrEmptySearchString
+ }
+
+ if params.Limit > 100 || params.Limit < 1 {
+ return ErrLimitOutOfRange
+ }
+
+ err := validateAnimeFields(&params.Fields)
+
+ return err
+}
+
+func validateAnimeRankingParams(params *RankingParams) error {
+ err := validateAnimeRankingType(params.RankingType)
+ if err != nil {
+ return err
+ }
+
+ if params.Limit > 500 || params.Limit < 1 {
+ return ErrLimitOutOfRange
+ }
+
+ err = validateAnimeFields(&params.Fields)
+
+ return err
+}
+
+func validateSeasonalParams(params *SeasonalParams) error {
+ // check if year is int
+
+ err := validateAnimeSeason(params.Season)
+ if err != nil {
+ return err
+ }
+
+ err = validateAnimeSeasonSort(params.Sort)
+ if err != nil {
+ return err
+ }
+
+ if params.Limit > 500 || params.Limit < 1 {
+ return ErrLimitOutOfRange
+ }
+
+ err = validateMangaFields(&params.Fields)
+
+ return err
+}
+
+func validateSuggestedParams(params *SuggestedParams) error {
+ if params.Limit > 100 || params.Limit < 1 {
+ return ErrLimitOutOfRange
+ }
+
+ return validateAnimeFields(&params.Fields)
+}
+
+func validateMangaSearchParams(params *SearchParams) error {
+ if strings.TrimSpace(params.SearchString) == "" {
+ return ErrEmptySearchString
+ }
+
+ if params.Limit > 100 || params.Limit < 1 {
+ return ErrLimitOutOfRange
+ }
+
+ err := validateMangaFields(&params.Fields)
+
+ return err
+}
+
+
+func validateMangaRankingParams(params *RankingParams) error {
+ err := validateMangaRankingType(params.RankingType)
+ if err != nil {
+ return err
+ }
+
+ if params.Limit > 500 || params.Limit < 1 {
+ return ErrLimitOutOfRange
+ }
+
+ err = validateMangaFields(&params.Fields)
+
+ return err
+}