From a507674426a6bc149cdbc741cdb25f4ee66a56dd Mon Sep 17 00:00:00 2001 From: Vidhu Kant Sharma Date: Mon, 14 Feb 2022 22:07:08 +0530 Subject: improved the UpdateAnime code --- user/anime/animelist.go | 13 +++++++++---- user/anime/request_handler.go | 16 +++++++++++++--- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/user/anime/animelist.go b/user/anime/animelist.go index 4f5eac5..8a673c1 100644 --- a/user/anime/animelist.go +++ b/user/anime/animelist.go @@ -20,6 +20,7 @@ import ( "encoding/json" "strconv" "fmt" + "log" "errors" a "github.com/MikunoNaka/mal2go/anime" e "github.com/MikunoNaka/mal2go/errhandlers" @@ -37,17 +38,21 @@ func (c AnimeListClient)DeleteAnime(id int) string { } // Update/Add an anime to user's anime list -func (c AnimeListClient)UpdateAnime(id int, data UpdateAnimeData) string { +func (c AnimeListClient)UpdateAnime(id int, data UpdateAnimeData) serverResponse { + /* NOTE: UpdateAnime only adds anime to the list + * It doesn't add new anime to the list. + * This might be a problem with MAL, + * I haven't researched this much */ endpoint := fmt.Sprintf("%s/anime/%d/my_list_status", BASE_URL, id) // turn data struct into json - pepe, err := json.Marshal(data) + jsonData, err := json.Marshal(data) if err != nil { - fmt.Println(err) + log.Println(err) } // finally make API request - res := c.putRequestHandler(endpoint, pepe) + res := c.putRequestHandler(endpoint, jsonData) return res } diff --git a/user/anime/request_handler.go b/user/anime/request_handler.go index 22c6e0b..3de8e4a 100644 --- a/user/anime/request_handler.go +++ b/user/anime/request_handler.go @@ -17,13 +17,19 @@ package anime import ( + "bytes" + "encoding/json" "io/ioutil" "log" "net/http" "strconv" - "bytes" ) +type serverResponse struct { + Message string + Error string +} + // Handles HTTP request with your OAuth token as a Header func (c AnimeListClient) requestHandler(endpoint, method string) string { // generate request @@ -55,7 +61,7 @@ func (c AnimeListClient) requestHandler(endpoint, method string) string { } // for PUT requests (used by UpdateAnime) -func (c AnimeListClient) putRequestHandler(endpoint string, data []uint8) string { +func (c AnimeListClient) putRequestHandler(endpoint string, data []uint8) serverResponse { // generate request req, err := http.NewRequest(http.MethodPut, endpoint, bytes.NewBuffer(data)) if err != nil { @@ -76,5 +82,9 @@ func (c AnimeListClient) putRequestHandler(endpoint string, data []uint8) string log.Fatal(err) } - return string(body) + // server response, ie message / error + var resp serverResponse + json.Unmarshal(body, &resp) + + return resp } -- cgit v1.2.3 From a5a96fe4673048d49f8f14665e4065e199b1179b Mon Sep 17 00:00:00 2001 From: Vidhu Kant Sharma Date: Mon, 14 Feb 2022 22:28:04 +0530 Subject: Added functionality to get authenticated user's info. More details to be added later --- user/client.go | 27 +++++++++++++++++++++++++++ user/request_handler.go | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ user/user.go | 36 ++++++++++++++++++++++++++++++++++++ user/user.structs.go | 30 ++++++++++++++++++++++++++++++ 4 files changed, 141 insertions(+) create mode 100644 user/client.go create mode 100644 user/request_handler.go create mode 100644 user/user.go create mode 100644 user/user.structs.go diff --git a/user/client.go b/user/client.go new file mode 100644 index 0000000..7d5b800 --- /dev/null +++ b/user/client.go @@ -0,0 +1,27 @@ +/* MAL2Go - MyAnimeList V2 API wrapper for Go + * Copyright (C) 2022 Vidhu Kant Sharma + + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ + +package user + +import ( + "net/http" +) + +// MyAnimeList Client for mal2go/anime package +type MALUserClient struct { + AuthToken, RefreshToken string + HttpClient http.Client +} diff --git a/user/request_handler.go b/user/request_handler.go new file mode 100644 index 0000000..da8c5f7 --- /dev/null +++ b/user/request_handler.go @@ -0,0 +1,48 @@ +/* MAL2Go - MyAnimeList V2 API wrapper for Go + * Copyright (C) 2022 Vidhu Kant Sharma + + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ + +package user + +import ( + "io/ioutil" + "log" + "net/http" +) + +// Handles HTTP request with your OAuth token as a Header +func (c MALUserClient) requestHandler(endpoint string) string { + // generate request + req, err := http.NewRequest("GET", endpoint, nil) + if err != nil { + log.Fatal(err) + } + req.Header.Add("Authorization", c.AuthToken) + + // do request + res, err := c.HttpClient.Do(req) + if err != nil { + log.Fatal(err) + } + defer res.Body.Close() + + // read body + body, err := ioutil.ReadAll(res.Body) + if err != nil { + log.Fatal(err) + } + + return string(body) +} diff --git a/user/user.go b/user/user.go new file mode 100644 index 0000000..31ac8dc --- /dev/null +++ b/user/user.go @@ -0,0 +1,36 @@ +/* MAL2Go - MyAnimeList V2 API wrapper for Go + * Copyright (C) 2022 Vidhu Kant Sharma + + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ + +package user + +import ( + "encoding/json" +) + +const BASE_URL string = "https://api.myanimelist.net/v2/users" + +// Get info of logged in user +func (c *MALUserClient) GetSelfUserInfo() UserInfo { + /* MAL only supports @me for this */ + endpoint := BASE_URL + "/@me?fields=anime_statistics" + + // get data from API + var userData UserInfo + data := c.requestHandler(endpoint) + json.Unmarshal([]byte(data), &userData) + + return userData +} diff --git a/user/user.structs.go b/user/user.structs.go new file mode 100644 index 0000000..b730033 --- /dev/null +++ b/user/user.structs.go @@ -0,0 +1,30 @@ +/* MAL2Go - MyAnimeList V2 API wrapper for Go + * Copyright (C) 2022 Vidhu Kant Sharma + + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ + +package user + +type UserInfo struct { + Id int `json:"id"` + Name string `json:"name"` + Picture string `json:"picture"` + Gender string `json:"gender"` + Birthday string `json:"birthday"` + Location string `json:"location"` + JoinedAt string `json:"joined_at"` + // TODO: Add AnimeStatistics + TimeZone string `json:"time_zone"` + IsSupporter bool `json:"is_supporter"` +} -- cgit v1.2.3 From 74a5f1ce1594d01ef7caeb3c5fcac047a7d8f9b3 Mon Sep 17 00:00:00 2001 From: Vidhu Kant Sharma Date: Mon, 14 Feb 2022 23:02:38 +0530 Subject: fixed UpdateAnime not working, though incomplete and kinda dangerous right now --- user/anime/animelist.go | 15 ++------------- user/anime/request_handler.go | 15 ++++++++++++--- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/user/anime/animelist.go b/user/anime/animelist.go index 8a673c1..78242ac 100644 --- a/user/anime/animelist.go +++ b/user/anime/animelist.go @@ -20,7 +20,6 @@ import ( "encoding/json" "strconv" "fmt" - "log" "errors" a "github.com/MikunoNaka/mal2go/anime" e "github.com/MikunoNaka/mal2go/errhandlers" @@ -39,20 +38,10 @@ func (c AnimeListClient)DeleteAnime(id int) string { // Update/Add an anime to user's anime list func (c AnimeListClient)UpdateAnime(id int, data UpdateAnimeData) serverResponse { - /* NOTE: UpdateAnime only adds anime to the list - * It doesn't add new anime to the list. - * This might be a problem with MAL, - * I haven't researched this much */ endpoint := fmt.Sprintf("%s/anime/%d/my_list_status", BASE_URL, id) - // turn data struct into json - jsonData, err := json.Marshal(data) - if err != nil { - log.Println(err) - } - - // finally make API request - res := c.putRequestHandler(endpoint, jsonData) + // make API request + res := c.putRequestHandler(endpoint, data) return res } diff --git a/user/anime/request_handler.go b/user/anime/request_handler.go index 3de8e4a..6f29d88 100644 --- a/user/anime/request_handler.go +++ b/user/anime/request_handler.go @@ -17,8 +17,9 @@ package anime import ( - "bytes" + "strings" "encoding/json" + "net/url" "io/ioutil" "log" "net/http" @@ -61,13 +62,21 @@ func (c AnimeListClient) requestHandler(endpoint, method string) string { } // for PUT requests (used by UpdateAnime) -func (c AnimeListClient) putRequestHandler(endpoint string, data []uint8) serverResponse { +func (c AnimeListClient) putRequestHandler(endpoint string, updateData UpdateAnimeData) serverResponse { + // TODO: make this do other stuff + p := url.Values{} + p.Set("score", strconv.Itoa(updateData.Score)) + p.Set("num_watched_episodes", strconv.Itoa(updateData.EpWatched)) + // generate request - req, err := http.NewRequest(http.MethodPut, endpoint, bytes.NewBuffer(data)) + req, err := http.NewRequest(http.MethodPut, endpoint, strings.NewReader(p.Encode())) if err != nil { log.Fatal(err) } req.Header.Add("Authorization", c.AuthToken) + // this makes the sending-data-to-server magic work + req.Header.Add("Content-Type", "application/x-www-form-urlencoded") + req.Header.Add("Content-Length", strconv.Itoa(len(p.Encode()))) // do request res, err := c.HttpClient.Do(req) -- cgit v1.2.3 From 831a57e8d065a01cefe40dd8545770064759eb13 Mon Sep 17 00:00:00 2001 From: Vidhu Kant Sharma Date: Tue, 15 Feb 2022 21:55:56 +0530 Subject: somehow made UpdateAnime work decently --- errhandlers/validators.go | 24 ++++++++++++++++++++++++ user/anime/animelist.go | 28 +++++++++++++++++++++++----- user/anime/animelist.structs.go | 18 +++++++++--------- user/anime/request_handler.go | 25 ++++++++++++++++++------- 4 files changed, 74 insertions(+), 21 deletions(-) diff --git a/errhandlers/validators.go b/errhandlers/validators.go index 6bf7a3f..1be61cb 100644 --- a/errhandlers/validators.go +++ b/errhandlers/validators.go @@ -122,3 +122,27 @@ func IsValidListStatus(status string) bool { } return false } + +// Checks if given anime score is valid +func IsValidScore(score int) bool { + if score >= 0 && score <= 10 { + return true + } + return false +} + +// Checks if given anime priority is valid +func IsValidPriority(priority int) bool { + if priority >= 0 && priority <= 2 { + return true + } + return false +} + +// Checks if given rewatch value is valid +func IsValidRewatchValue(r int) bool { + if r >= 0 && r <= 5 { + return true + } + return false +} diff --git a/user/anime/animelist.go b/user/anime/animelist.go index 78242ac..3065919 100644 --- a/user/anime/animelist.go +++ b/user/anime/animelist.go @@ -37,12 +37,31 @@ func (c AnimeListClient)DeleteAnime(id int) string { } // Update/Add an anime to user's anime list -func (c AnimeListClient)UpdateAnime(id int, data UpdateAnimeData) serverResponse { +func (c AnimeListClient)UpdateAnime(id int, data UpdateAnimeData) (serverResponse, error) { endpoint := fmt.Sprintf("%s/anime/%d/my_list_status", BASE_URL, id) + // checks if specified list status is valid + if !e.IsValidListStatus(data.Status) { + return serverResponse{}, errors.New(fmt.Sprintf("UpdateAnime: Invalid list status: \"%s\"", data.Status)) + } + + // checks if specified score is valid + if !e.IsValidScore(data.Score) { + return serverResponse{}, errors.New(fmt.Sprintf("UpdateAnime: Invalid score: %d doesn't lie within 0-10", data.Score)) + } + + // checks if specified priority is valid + if !e.IsValidPriority(data.Priority) { + return serverResponse{}, errors.New(fmt.Sprintf("UpdateAnime: Invalid priority: %d doesn't lie within 0-2", data.Priority)) + } + + // checks if specified rewatch value is valid + if !e.IsValidRewatchValue(data.RewatchValue) { + return serverResponse{}, errors.New(fmt.Sprintf("UpdateAnime: Invalid rewatch value: %d doesn't lie within 0-5", data.RewatchValue)) + } + // make API request - res := c.putRequestHandler(endpoint, data) - return res + return c.putRequestHandler(endpoint, data), nil } // Get authenticated user's anime list @@ -50,8 +69,7 @@ func (c AnimeListClient) GetAnimeList(user, status, sort string, limit, offset i var userAnimeList a.AnimeList // error handling for limit and offset limitsErr := e.LimitsErrHandler(limit, offset, maxListLimit) - if limitsErr != nil { - return userAnimeList, limitsErr + if limitsErr != nil { return userAnimeList, limitsErr } // checks if valid sort is specified diff --git a/user/anime/animelist.structs.go b/user/anime/animelist.structs.go index d874f7b..06c40d1 100644 --- a/user/anime/animelist.structs.go +++ b/user/anime/animelist.structs.go @@ -29,14 +29,14 @@ type AnimeListRaw struct { } type UpdateAnimeData struct { - Status string `json:"status"` - IsRewatching bool `json:"is_rewatching"` - Score int `json:"score"` - EpWatched int `json:"num_watched_episodes"` - Priority int `json:"priority"` - TimesRewatched int `json:"num_times_rewatched"` + Status string + IsRewatching bool + Score int + EpWatched int + Priority int + TimesRewatched int // NOTE: idk what RewatchValue is - RewatchValue int `json:"rewatch_value"` - Tags string `json:"tags"` - Comments string `json:"comments"` + RewatchValue int + Tags string + Comments string } diff --git a/user/anime/request_handler.go b/user/anime/request_handler.go index 6f29d88..e44dab1 100644 --- a/user/anime/request_handler.go +++ b/user/anime/request_handler.go @@ -2,8 +2,7 @@ * Copyright (C) 2022 Vidhu Kant Sharma * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or + * it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, @@ -64,19 +63,31 @@ func (c AnimeListClient) requestHandler(endpoint, method string) string { // for PUT requests (used by UpdateAnime) func (c AnimeListClient) putRequestHandler(endpoint string, updateData UpdateAnimeData) serverResponse { // TODO: make this do other stuff - p := url.Values{} - p.Set("score", strconv.Itoa(updateData.Score)) - p.Set("num_watched_episodes", strconv.Itoa(updateData.EpWatched)) + params := url.Values{} + + /* NOTE: THIS WILL OVERWRITE ANY DATA THAT + * IS NOT SPECIFIED AND SET IT TO NULL */ + params.Set("status", updateData.Status) + params.Set("is_rewatching", strconv.FormatBool(updateData.IsRewatching)) + params.Set("score", strconv.Itoa(updateData.Score)) + params.Set("num_watched_episodes", strconv.Itoa(updateData.EpWatched)) + params.Set("priority", strconv.Itoa(updateData.Priority)) + params.Set("num_times_rewatched", strconv.Itoa(updateData.TimesRewatched)) + params.Set("rewatch_value", strconv.Itoa(updateData.RewatchValue)) + params.Set("tags", updateData.Tags) + params.Set("comments", updateData.Comments) + + paramsEncoded := params.Encode() // generate request - req, err := http.NewRequest(http.MethodPut, endpoint, strings.NewReader(p.Encode())) + req, err := http.NewRequest(http.MethodPut, endpoint, strings.NewReader(paramsEncoded)) if err != nil { log.Fatal(err) } req.Header.Add("Authorization", c.AuthToken) // this makes the sending-data-to-server magic work req.Header.Add("Content-Type", "application/x-www-form-urlencoded") - req.Header.Add("Content-Length", strconv.Itoa(len(p.Encode()))) + req.Header.Add("Content-Length", strconv.Itoa(len(paramsEncoded))) // do request res, err := c.HttpClient.Do(req) -- cgit v1.2.3 From 3269df237abce92172e115aa62e9c5d6e4652765 Mon Sep 17 00:00:00 2001 From: Vidhu Kant Sharma Date: Wed, 16 Feb 2022 22:32:26 +0530 Subject: renamed client to something more memorable --- user/anime/client.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/user/anime/client.go b/user/anime/client.go index e9a99d3..eeba194 100644 --- a/user/anime/client.go +++ b/user/anime/client.go @@ -1,4 +1,4 @@ -/* mal2go - MyAnimeList V2 API wrapper for Go +/* MAL2Go - MyAnimeList V2 API wrapper for Go * Copyright (C) 2022 Vidhu Kant Sharma * This program is free software: you can redistribute it and/or modify @@ -20,8 +20,8 @@ import ( "net/http" ) -// MyAnimeList Client for mal2go/anime package -type AnimeListClient struct { +// MyAnimeList Client for mal2go/user/anime package +type Client struct { AuthToken, RefreshToken string HttpClient http.Client } -- cgit v1.2.3 From 5c94f2f8e7026b9a4dff874edbf3b4fa3b266516 Mon Sep 17 00:00:00 2001 From: Vidhu Kant Sharma Date: Wed, 16 Feb 2022 22:43:23 +0530 Subject: Defined different functions to update different anime fields --- go.mod | 4 +- go.sum | 2 + user/anime/animelist.go | 34 +------ user/anime/animelist.structs.go | 2 +- user/anime/request_handler.go | 28 ++---- user/anime/update_animelist.go | 203 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 219 insertions(+), 54 deletions(-) create mode 100644 go.sum create mode 100644 user/anime/update_animelist.go diff --git a/go.mod b/go.mod index 5fe48c9..5bf033b 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,5 @@ -module github.com/MikunoNaka/mal2go +module github.com/MikunoNaka/MAL2Go go 1.17 + +require github.com/MikunoNaka/mal2go v0.0.0-20220213112712-541c75949e86 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..8148e90 --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/MikunoNaka/mal2go v0.0.0-20220213112712-541c75949e86 h1:hpz3DsUPkaznnO3a1nZZTQeIll0yKTGGWKM0fxvnCxc= +github.com/MikunoNaka/mal2go v0.0.0-20220213112712-541c75949e86/go.mod h1:fKunJNVMPoiH/yahvQDy9cFdjRkL+w+DDzeOlL4lMEU= diff --git a/user/anime/animelist.go b/user/anime/animelist.go index 3065919..bbc7d7a 100644 --- a/user/anime/animelist.go +++ b/user/anime/animelist.go @@ -1,4 +1,4 @@ -/* mal2go - MyAnimeList V2 API wrapper for Go +/* MAL2Go - MyAnimeList V2 API wrapper for Go * Copyright (C) 2022 Vidhu Kant Sharma * This program is free software: you can redistribute it and/or modify @@ -29,43 +29,15 @@ const BASE_URL string = "https://api.myanimelist.net/v2" const maxListLimit int = 1000 // Delete an anime from user's anime list -func (c AnimeListClient)DeleteAnime(id int) string { +func (c Client)DeleteAnime(id int) string { endpoint := fmt.Sprintf("%s/anime/%d/my_list_status", BASE_URL, id) /* Returns 200 if anime successfully deleted * Alternatively returns 404 if anime not in user's anime list */ return c.requestHandler(endpoint, "DELETE") } -// Update/Add an anime to user's anime list -func (c AnimeListClient)UpdateAnime(id int, data UpdateAnimeData) (serverResponse, error) { - endpoint := fmt.Sprintf("%s/anime/%d/my_list_status", BASE_URL, id) - - // checks if specified list status is valid - if !e.IsValidListStatus(data.Status) { - return serverResponse{}, errors.New(fmt.Sprintf("UpdateAnime: Invalid list status: \"%s\"", data.Status)) - } - - // checks if specified score is valid - if !e.IsValidScore(data.Score) { - return serverResponse{}, errors.New(fmt.Sprintf("UpdateAnime: Invalid score: %d doesn't lie within 0-10", data.Score)) - } - - // checks if specified priority is valid - if !e.IsValidPriority(data.Priority) { - return serverResponse{}, errors.New(fmt.Sprintf("UpdateAnime: Invalid priority: %d doesn't lie within 0-2", data.Priority)) - } - - // checks if specified rewatch value is valid - if !e.IsValidRewatchValue(data.RewatchValue) { - return serverResponse{}, errors.New(fmt.Sprintf("UpdateAnime: Invalid rewatch value: %d doesn't lie within 0-5", data.RewatchValue)) - } - - // make API request - return c.putRequestHandler(endpoint, data), nil -} - // Get authenticated user's anime list -func (c AnimeListClient) GetAnimeList(user, status, sort string, limit, offset int) (a.AnimeList, error){ +func (c Client) GetAnimeList(user, status, sort string, limit, offset int) (a.AnimeList, error){ var userAnimeList a.AnimeList // error handling for limit and offset limitsErr := e.LimitsErrHandler(limit, offset, maxListLimit) diff --git a/user/anime/animelist.structs.go b/user/anime/animelist.structs.go index 06c40d1..cee47d2 100644 --- a/user/anime/animelist.structs.go +++ b/user/anime/animelist.structs.go @@ -1,4 +1,4 @@ -/* mal2go - MyAnimeList V2 API wrapper for Go +/* MAL2Go - MyAnimeList V2 API wrapper for Go * Copyright (C) 2022 Vidhu Kant Sharma * This program is free software: you can redistribute it and/or modify diff --git a/user/anime/request_handler.go b/user/anime/request_handler.go index e44dab1..abc0afc 100644 --- a/user/anime/request_handler.go +++ b/user/anime/request_handler.go @@ -1,4 +1,4 @@ -/* mal2go - MyAnimeList V2 API wrapper for Go +/* MAL2Go - MyAnimeList V2 API wrapper for Go * Copyright (C) 2022 Vidhu Kant Sharma * This program is free software: you can redistribute it and/or modify @@ -16,13 +16,13 @@ package anime import ( - "strings" "encoding/json" - "net/url" "io/ioutil" "log" "net/http" + "net/url" "strconv" + "strings" ) type serverResponse struct { @@ -31,7 +31,7 @@ type serverResponse struct { } // Handles HTTP request with your OAuth token as a Header -func (c AnimeListClient) requestHandler(endpoint, method string) string { +func (c Client) requestHandler(endpoint, method string) string { // generate request req, err := http.NewRequest(method, endpoint, nil) if err != nil { @@ -60,23 +60,8 @@ func (c AnimeListClient) requestHandler(endpoint, method string) string { return string(body) } -// for PUT requests (used by UpdateAnime) -func (c AnimeListClient) putRequestHandler(endpoint string, updateData UpdateAnimeData) serverResponse { - // TODO: make this do other stuff - params := url.Values{} - - /* NOTE: THIS WILL OVERWRITE ANY DATA THAT - * IS NOT SPECIFIED AND SET IT TO NULL */ - params.Set("status", updateData.Status) - params.Set("is_rewatching", strconv.FormatBool(updateData.IsRewatching)) - params.Set("score", strconv.Itoa(updateData.Score)) - params.Set("num_watched_episodes", strconv.Itoa(updateData.EpWatched)) - params.Set("priority", strconv.Itoa(updateData.Priority)) - params.Set("num_times_rewatched", strconv.Itoa(updateData.TimesRewatched)) - params.Set("rewatch_value", strconv.Itoa(updateData.RewatchValue)) - params.Set("tags", updateData.Tags) - params.Set("comments", updateData.Comments) - +// for PUT requests (used for updating anime) +func (c Client) putRequestHandler(endpoint string, params url.Values) serverResponse { paramsEncoded := params.Encode() // generate request @@ -102,6 +87,7 @@ func (c AnimeListClient) putRequestHandler(endpoint string, updateData UpdateAni log.Fatal(err) } + // TODO: there are other serverResponses. Add them // server response, ie message / error var resp serverResponse json.Unmarshal(body, &resp) diff --git a/user/anime/update_animelist.go b/user/anime/update_animelist.go new file mode 100644 index 0000000..5a6883c --- /dev/null +++ b/user/anime/update_animelist.go @@ -0,0 +1,203 @@ +/* MAL2Go - MyAnimeList V2 API wrapper for Go + * Copyright (C) 2022 Vidhu Kant Sharma + + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ + +package anime + +import ( + e "github.com/MikunoNaka/mal2go/errhandlers" + "errors" + "fmt" + "net/url" + "strconv" +) + +// generate the endpoint url with the anime id +func endpointGenerator(id int) string { + return fmt.Sprintf("%s/anime/%d/my_list_status", BASE_URL, id) +} + +// update just an anime's status +func (c Client)SetStatus(id int, status string) (serverResponse, error) { + endpoint := endpointGenerator(id) + + // checks if specified list status is valid + if !e.IsValidListStatus(status) { + return serverResponse{}, errors.New(fmt.Sprintf("SetStatus: Invalid list status: \"%s\"", status)) + } + + // data to be sent to the server + params := url.Values{} + params.Set("status", status) + + // make API request + return c.putRequestHandler(endpoint, params), nil +} + +// update just an anime's num of episodes watched +func (c Client)SetWatchedEpisodes(id int, episodesWatched int) (serverResponse, error) { + endpoint := endpointGenerator(id) + + // data to be sent to the server + params := url.Values{} + params.Set("num_watched_episodes", strconv.Itoa(episodesWatched)) + + // make API request + return c.putRequestHandler(endpoint, params), nil +} + +// update just an anime's rewatching status +func (c Client)SetIsRewatching(id int, isRewatching bool) (serverResponse, error) { + endpoint := endpointGenerator(id) + + // data to be sent to the server + params := url.Values{} + params.Set("is_rewatching", strconv.FormatBool(isRewatching)) + + // make API request + return c.putRequestHandler(endpoint, params), nil +} + +// update just the anime's score +func (c Client)SetScore(id int, score int) (serverResponse, error) { + endpoint := endpointGenerator(id) + + // checks if specified score is valid + if !e.IsValidScore(score) { + return serverResponse{}, errors.New(fmt.Sprintf("SetScore: Invalid score: %d doesn't lie within 0-10", score)) + } + + // data to be sent to the server + params := url.Values{} + params.Set("score", strconv.Itoa(score)) + + // make API request + return c.putRequestHandler(endpoint, params), nil +} + +// update just an anime's priority +func (c Client)SetPriority(id int, priority int) (serverResponse, error) { + endpoint := endpointGenerator(id) + + // checks if specified priority is valid + if !e.IsValidPriority(priority) { + return serverResponse{}, errors.New(fmt.Sprintf("SetPriority: Invalid priority: %d doesn't lie within 0-2", priority)) + } + + // data to be sent to the server + params := url.Values{} + params.Set("priority", strconv.Itoa(priority)) + + // make API request + return c.putRequestHandler(endpoint, params), nil +} + +// update just an anime's rewatch value +func (c Client)SetRewatchValue(id int, rewatchValue int) (serverResponse, error) { + endpoint := endpointGenerator(id) + + // checks if specified rewatch value is valid + if !e.IsValidRewatchValue(rewatchValue) { + return serverResponse{}, errors.New(fmt.Sprintf("SetRewatchValue: Invalid rewatch value: %d doesn't lie within 0-5", rewatchValue)) + } + + // data to be sent to the server + params := url.Values{} + params.Set("rewatch_value", strconv.Itoa(rewatchValue)) + + // make API request + return c.putRequestHandler(endpoint, params), nil +} + +// update just an anime's rewatch count +func (c Client)UpdateRewatchCount(id int, rewatchCount int) (serverResponse, error) { + endpoint := endpointGenerator(id) + + // data to be sent to the server + params := url.Values{} + params.Set("num_times_rewatched", strconv.Itoa(rewatchCount)) + + // make API request + return c.putRequestHandler(endpoint, params), nil +} + +// update just an anime's tags +func (c Client)UpdateTags(id int, tags string) (serverResponse, error) { + endpoint := endpointGenerator(id) + + // data to be sent to the server + params := url.Values{} + params.Set("tags", tags) + + // make API request + return c.putRequestHandler(endpoint, params), nil +} + +// update just an anime's comments +func (c Client)UpdateComments(id int, comments string) (serverResponse, error) { + endpoint := endpointGenerator(id) + + // data to be sent to the server + params := url.Values{} + params.Set("comments", comments) + + // make API request + return c.putRequestHandler(endpoint, params), nil +} + +/* This will overwrite everything + * i won't use it.. but it's pretty flexible + * so this will stay here */ +// Update/Add an anime to user's anime list +func (c Client)UpdateAnime(id int, data UpdateAnimeData) (serverResponse, error) { + endpoint := endpointGenerator(id) + + // checks if specified list status is valid + if !e.IsValidListStatus(data.Status) { + return serverResponse{}, errors.New(fmt.Sprintf("UpdateAnime: Invalid list status: \"%s\"", data.Status)) + } + + // checks if specified score is valid + if !e.IsValidScore(data.Score) { + return serverResponse{}, errors.New(fmt.Sprintf("UpdateAnime: Invalid score: %d doesn't lie within 0-10", data.Score)) + } + + // checks if specified priority is valid + if !e.IsValidPriority(data.Priority) { + return serverResponse{}, errors.New(fmt.Sprintf("UpdateAnime: Invalid priority: %d doesn't lie within 0-2", data.Priority)) + } + + // checks if specified rewatch value is valid + if !e.IsValidRewatchValue(data.RewatchValue) { + return serverResponse{}, errors.New(fmt.Sprintf("UpdateAnime: Invalid rewatch value: %d doesn't lie within 0-5", data.RewatchValue)) + } + + params := url.Values{} + + /* NOTE: THIS WILL OVERWRITE ANY DATA THAT + * IS NOT SPECIFIED AND SET IT TO NULL */ + params.Set("status", data.Status) + params.Set("is_rewatching", strconv.FormatBool(data.IsRewatching)) + params.Set("score", strconv.Itoa(data.Score)) + params.Set("num_watched_episodes", strconv.Itoa(data.EpWatched)) + params.Set("priority", strconv.Itoa(data.Priority)) + params.Set("num_times_rewatched", strconv.Itoa(data.TimesRewatched)) + params.Set("rewatch_value", strconv.Itoa(data.RewatchValue)) + params.Set("tags", data.Tags) + params.Set("comments", data.Comments) + + // make API request + return c.putRequestHandler(endpoint, params), nil +} + -- cgit v1.2.3