aboutsummaryrefslogtreecommitdiff
path: root/user/anime
diff options
context:
space:
mode:
Diffstat (limited to 'user/anime')
-rw-r--r--user/anime/animelist.go108
-rw-r--r--user/anime/animelist.structs.go42
-rw-r--r--user/anime/client.go27
-rw-r--r--user/anime/request_handler.go80
4 files changed, 257 insertions, 0 deletions
diff --git a/user/anime/animelist.go b/user/anime/animelist.go
new file mode 100644
index 0000000..4f5eac5
--- /dev/null
+++ b/user/anime/animelist.go
@@ -0,0 +1,108 @@
+/* mal2go - MyAnimeList V2 API wrapper for Go
+ * Copyright (C) 2022 Vidhu Kant Sharma <vidhukant@protonmail.ch>
+
+ * 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 <https://www.gnu.org/licenses/>. */
+
+package anime
+
+import (
+ "encoding/json"
+ "strconv"
+ "fmt"
+ "errors"
+ a "github.com/MikunoNaka/mal2go/anime"
+ e "github.com/MikunoNaka/mal2go/errhandlers"
+)
+
+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 {
+ 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) string {
+ endpoint := fmt.Sprintf("%s/anime/%d/my_list_status", BASE_URL, id)
+
+ // turn data struct into json
+ pepe, err := json.Marshal(data)
+ if err != nil {
+ fmt.Println(err)
+ }
+
+ // finally make API request
+ res := c.putRequestHandler(endpoint, pepe)
+ return res
+}
+
+// Get authenticated user's anime list
+func (c AnimeListClient) 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)
+ if limitsErr != nil {
+ return userAnimeList, limitsErr
+ }
+
+ // checks if valid sort is specified
+ if !e.IsValidListSort(sort) {
+ return userAnimeList, errors.New(fmt.Sprintf("GetAnimeList: Invalid sort specified: \"%s\"", sort))
+ }
+
+ // checks if valid status is specified
+ if status != "" && !e.IsValidListStatus(status) {
+ return userAnimeList, errors.New(fmt.Sprintf("GetAnimeList: Invalid status specified: \"%s\"", status))
+ }
+
+ // get own list if user not specified
+ if user == "" {
+ user = "@me"
+ }
+
+ // if status is "" it returns all anime
+ var endpoint string
+ if status == "" {
+ endpoint = BASE_URL + "/users/" + user + "/animelist?sort=" + sort + "&limit=" + strconv.Itoa(limit) + "&offset=" + strconv.Itoa(offset)
+ } else {
+ endpoint = BASE_URL + "/users/" + user + "/animelist?status=" + status + "&sort=" + sort + "&limit=" + strconv.Itoa(limit) + "&offset=" + strconv.Itoa(offset)
+ }
+
+ // get data from API
+ var animeListData AnimeListRaw
+ data := c.requestHandler(endpoint, "GET")
+ json.Unmarshal([]byte(data), &animeListData)
+
+ // set MyListStatus for each element and add it to array
+ var animes []a.Anime
+ for _, element := range animeListData.Data {
+ a := element.Anime
+ a.MyListStatus = element.ListStatus
+
+ animes = append(animes, a)
+ }
+
+ // finally create AnimeList
+ userAnimeList = a.AnimeList {
+ Animes: animes,
+ Paging: animeListData.Paging,
+ }
+
+ return userAnimeList, nil
+}
+
diff --git a/user/anime/animelist.structs.go b/user/anime/animelist.structs.go
new file mode 100644
index 0000000..d874f7b
--- /dev/null
+++ b/user/anime/animelist.structs.go
@@ -0,0 +1,42 @@
+/* mal2go - MyAnimeList V2 API wrapper for Go
+ * Copyright (C) 2022 Vidhu Kant Sharma <vidhukant@protonmail.ch>
+
+ * 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 <https://www.gnu.org/licenses/>. */
+
+package anime
+
+import (
+ "github.com/MikunoNaka/mal2go/anime"
+)
+
+type AnimeListRaw struct {
+ Data []struct {
+ Anime anime.Anime `json:"node"`
+ ListStatus anime.ListStatus `json:"list_status"`
+ } `json:"data"`
+ Paging anime.ListPaging `json:"paging"`
+}
+
+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"`
+ // NOTE: idk what RewatchValue is
+ RewatchValue int `json:"rewatch_value"`
+ Tags string `json:"tags"`
+ Comments string `json:"comments"`
+}
diff --git a/user/anime/client.go b/user/anime/client.go
new file mode 100644
index 0000000..e9a99d3
--- /dev/null
+++ b/user/anime/client.go
@@ -0,0 +1,27 @@
+/* mal2go - MyAnimeList V2 API wrapper for Go
+ * Copyright (C) 2022 Vidhu Kant Sharma <vidhukant@protonmail.ch>
+
+ * 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 <https://www.gnu.org/licenses/>. */
+
+package anime
+
+import (
+ "net/http"
+)
+
+// MyAnimeList Client for mal2go/anime package
+type AnimeListClient struct {
+ AuthToken, RefreshToken string
+ HttpClient http.Client
+}
diff --git a/user/anime/request_handler.go b/user/anime/request_handler.go
new file mode 100644
index 0000000..22c6e0b
--- /dev/null
+++ b/user/anime/request_handler.go
@@ -0,0 +1,80 @@
+/* mal2go - MyAnimeList V2 API wrapper for Go
+ * Copyright (C) 2022 Vidhu Kant Sharma <vidhukant@protonmail.ch>
+
+ * 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 <https://www.gnu.org/licenses/>. */
+
+package anime
+
+import (
+ "io/ioutil"
+ "log"
+ "net/http"
+ "strconv"
+ "bytes"
+)
+
+// Handles HTTP request with your OAuth token as a Header
+func (c AnimeListClient) requestHandler(endpoint, method string) string {
+ // generate request
+ req, err := http.NewRequest(method, 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)
+ }
+
+ // for DeleteAnime, its endpoint returns null data
+ if method == "DELETE" {
+ return strconv.Itoa(res.StatusCode)
+ }
+
+ return string(body)
+}
+
+// for PUT requests (used by UpdateAnime)
+func (c AnimeListClient) putRequestHandler(endpoint string, data []uint8) string {
+ // generate request
+ req, err := http.NewRequest(http.MethodPut, endpoint, bytes.NewBuffer(data))
+ 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)
+}