aboutsummaryrefslogtreecommitdiff
path: root/README.md
diff options
context:
space:
mode:
Diffstat (limited to 'README.md')
-rw-r--r--README.md565
1 files changed, 565 insertions, 0 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..ba8e532
--- /dev/null
+++ b/README.md
@@ -0,0 +1,565 @@
+# mg
+
+mg is a free and open source library for accessing the official MyAnimeList V2 API using Go. All endpoints are supported except forums as of now.
+
+If you find any bugs, please write to me at <vidhukant@vidhukant.com>
+
+<https://mg.vidhukant.com>
+
+# License
+
+Licenced under GNU General Public Licence V3
+
+GNU GPL License: [link](https://mikunonaka.net/mg/tree/LICENSE)
+
+Copyright (c) 2022-2023 Vidhu Kant Sharma
+
+# Documentation
+
+***for v1.0.1+***
+
+*Documentation might be incomplete or buggy. If you want to submit any changes, or need any help, please feel free to contact me at the given E-mail address.*
+
+## Initializing the mg client
+
+There are 2 ways to authenticate with mg:
+- ClientAuth
+
+ With ClientAuth, you just need to use your MyAnimeList Client ID to access the read-only resources.
+ You cannot do actions that require logging in. To use ClientAuth, set `client.ClientAuthOnly` to `true`.
+- MainAuth
+
+ With MainAuth, you can perform actions like getting recommendations, or editing an anime/manga list.
+ For this, you need to generate a Bearer token; for which a Client ID is still needed.
+ `ClientAuthOnly` must be set to `false` to use MainAuth.
+
+Go to <https://myanimelist.net/apiconfig> to generate your very own Client ID!
+
+Check out [this script](https://git.mikunonaka.net/mal-authtoken-generator/about/)
+to generate an auth token, whilst I work on adding this functionality to mg!
+It has been deprecated and may or may not work, but it's better than nothing!
+
+Also check out [this guide](https://myanimelist.net/blog.php?eid=835707) for more info; or just in case if this script doesn't work!
+
+``` go
+package main
+
+import (
+ "vidhukant.com/mg"
+)
+
+func main() {
+ var client mg.Client
+
+ // either this
+ client.MainAuth = "Bearer <your token here>"
+
+ // or this
+ client.ClientAuth = "<your client id here>"
+ client.ClientAuthOnly = true
+
+ // ...
+}
+```
+
+# Anime
+
+## Searching for an anime
+
+`MainAuth` or `ClientAuth`
+
+``` go
+// ...
+
+var animes []mg.Anime
+
+params := mg.SearchParamsNew()
+params.SearchString = "mushishi"
+
+// optional; these are the default values
+params.Limit = 100 // max = 100
+params.Offset = 0
+params.NSFW = false
+params.Fields = []string{}
+
+err := client.SearchAnime(&animes, params)
+if err != nil {
+ fmt.Println(err)
+}
+
+for _, anime := range animes {
+ fmt.Println(anime.Title)
+}
+
+// ...
+```
+
+## Getting an anime's information
+
+`MainAuth` or `ClientAuth`
+
+_searching can be a bit inaccurate, if you know the anime's ID (obtain it with SearchAnime!) and want to get detailed information, use this._
+
+``` go
+// ...
+
+var anime mg.Anime
+
+err := client.GetAnimeById(&anime, /*anime id*/ 457, /*fields*/ []string{})
+if err != nil {
+ fmt.Println(err)
+}
+
+// ...
+```
+
+## Getting anime ranking list
+
+`MainAuth` or `ClientAuth`
+
+Accepted ranking types:
+| Ranking Type | Description |
+|----------------------------|-------------------------|
+| mg.RankingTypeAll | Top Anime Series |
+| mg.RankingTypeByPopularity | Top Anime by Popularity |
+| mg.RankingTypeFavorite | Top Favorited Anime |
+| mg.RankingTypeAiring | Top Airing Anime |
+| mg.RankingTypeUpcoming | Top Upcoming Anime |
+| mg.RankingTypeTV | Top Anime TV Series |
+| mg.RankingTypeOVA | Top Anime OVA Series |
+| mg.RankingTypeMovie | Top Anime Movies |
+| mg.RankingTypeSpecial | Top Anime Specials |
+
+## Getting seasonal animes
+
+`MainAuth` or `ClientAuth`
+
+Accepted seasons:
+- `mg.SeasonWinter`
+- `mg.SeasonSpring`
+- `mg.SeasonSummer`
+- `mg.SeasonFall`
+
+Accepted sorts:
+- `mg.SeasonSortByAnimeScore` (descending)
+- `mg.SeasonSortByNumListUsers` (descending)
+
+
+``` go
+// ...
+
+var seasonals []mg.Anime
+
+params := mg.SeasonalParamsNew()
+
+params.Year = "2023" // required
+params.Season = mg.SeasonFall // required
+
+// optional; these are the default values
+params.Sort = mg.SeasonSortByAnimeScore
+params.Limit = 100 // max = 500
+params.Offset = 0
+params.NSFW = false
+params.Fields = []string{}
+
+err := client.GetSeasonalAnime(&seasonals, params)
+if err != nil {
+ fmt.Println(err)
+}
+
+// ...
+```
+
+## Getting suggested animes
+
+`MainAuth` only
+
+``` go
+// ...
+
+var suggestedAnimes []mg.Anime
+
+params := mg.SuggestedParamsNew()
+
+// optional; these are the default values
+params.Limit = 100 // max = 100
+params.Offset = 0
+params.NSFW = false
+params.Fields = []string{}
+
+err := client.GetSeasonalAnime(&suggestedAnimes, params)
+if err != nil {
+ fmt.Println(err)
+}
+
+// ...
+```
+
+## Get any user's anime list
+
+`MainAuth` or `ClientAuth`
+
+This returns a boolean telling us if there is a next page on this user's list.
+Simply increment the offset by the limit and create a new request in order to get the next page.
+
+In order to get the complete list, repeat the process until `nextPageExists` becomes false.
+
+Accepted statuses:
+- `mg.ListStatusAll`
+- `mg.ListStatusWatching`
+- `mg.ListStatusCompleted`
+- `mg.ListStatusOnHold`
+- `mg.ListStatusDropped`
+- `mg.ListStatusPTW`
+
+Accepted list sorts:
+- `mg.SortByListScore` (descending)
+- `mg.SortByListUpdatedAt` (descending)
+- `mg.SortByAnimeTitle` (ascending)
+- `mg.SortByAnimeStartDate` (descending)
+- `mg.SortByAnimeId` (ascending) (beta according to MAL)
+
+``` go
+// ...
+
+var animes []mg.Anime
+
+params := mg.ListParamsNew()
+
+// optional; these are the default values
+params.Username = "@me" // can speciy any public account
+params.Status = mg.ListStatusAll
+params.Sort = mg.SortByListScore
+params.Limit = 100 // max = 1000
+params.Offset = 0
+params.NSFW = false
+params.Fields = []string{}
+
+nextPageExists, err := client.GetAnimeList(&animes, params)
+if err != nil {
+ fmt.Println(err)
+}
+
+// ...
+```
+
+## Updating an anime
+
+`MainAuth` only
+
+Updates an anime in the the currently logged in user's anime list.
+Adds the anime if it's not in the list.
+
+Accepted statuses:
+- `mg.ListStatusWatching`
+- `mg.ListStatusCompleted`
+- `mg.ListStatusOnHold`
+- `mg.ListStatusDropped`
+- `mg.ListStatusPTW`
+
+Score range: `0` - `10`
+
+Priority range: `0` - `2`
+| Priority | Description |
+|----------|-------------|
+| 0 | Low |
+| 1 | Medium |
+| 2 | High |
+
+RewatchValue range: `0` - `5`
+| RewatchValue | Description |
+|--------------|-------------|
+| 0 | None |
+| 1 | Very Low |
+| 2 | Low |
+| 3 | Medium |
+| 4 | High |
+| 5 | Very High |
+
+``` go
+// ...
+
+var res AnimeUpdateResponse
+
+// can omit any field but keep at least 1!
+params := map[string]interface{} {
+ mg.Status: mg.ListStatusCompleted,
+ mg.IsRewatching: false,
+ mg.Score: 10,
+ mg.EpisodesWatched: 26,
+ mg.Priority: 2,
+ mg.TimesRewatched: 2,
+ mg.RewatchValue: 5,
+ mg.Tags: "tags",
+ mg.Comments: "comments",
+}
+
+err := client.UpdateAnime(&res, /*anime id*/ 457, params)
+if err != nil {
+ fmt.Println(err)
+}
+
+// ...
+```
+
+## Deleting an anime from list
+
+`MainAuth` only
+
+Deletes the anime from currently logged in user's anime list.
+Returns an error if anime is already not in the list.
+
+``` go
+// ...
+
+err := client.DeleteAnime(/*anime id*/ 457)
+if err != nil {
+ fmt.Println(err)
+}
+
+// ...
+```
+
+# Manga
+
+## Searching for a manga
+
+`MainAuth` or `ClientAuth`
+
+_also works for light novels, etc_
+
+``` go
+// ...
+
+var mangas []mg.Manga
+
+carams := mg.SearchParamsNew()
+carams.SearchString = "empty box and zeroth maria"
+
+// optional; these are the default values
+params.Limit = 100
+params.Offset = 0
+params.NSFW = false
+params.Fields = []string{}
+
+err := client.SearchManga(&mangas, params)
+if err != nil {
+ fmt.Println(err)
+}
+
+for _, manga range mangas {
+ fmt.Println(manga.Title)
+}
+
+// ...
+```
+
+## Getting a manga's information
+
+`MainAuth` or `ClientAuth`
+
+_searching can be a bit inaccurate, if you know the manga's ID (obtain it with SearchManga!) and want to get detailed information, use this._
+
+``` go
+// ...
+
+var manga mg.Manga
+
+err := client.GetMangaById(&manga, /*manga id*/ 55215, /*fields*/ []string{})
+if err != nil {
+ fmt.Println(err)
+}
+
+// ...
+```
+
+## Getting manga ranking list
+
+`MainAuth` or `ClientAuth`
+
+Accepted ranking types:
+| RankingType | Description |
+|----------------------------|----------------|
+| mg.RankingTypeAll | All |
+| mg.RankingTypeByPopularity | Most Popular |
+| mg.RankingTypeFavorite | Most Favorited |
+| mg.RankingTypeManga | Top Manga |
+| mg.RankingTypeNovel | Top Novels |
+| mg.RankingTypeOneShot | Top One-shots |
+| mg.RankingTypeDoujin | Top Doujinshi |
+| mg.RankingTypeManhwa | Top Manhwa |
+| mg.RankingTypeManhua | Top Manhua |
+
+*RankedManga is just the Manga struct with an extra field `RankNum int`*
+
+``` go
+// ...
+
+var rankingList []mg.RankedManga
+
+params := mg.RankingParamsNew()
+
+// optional; these are the default values
+params.RankingType = mg.RankingTypeAll
+params.Limit = 100 // max = 500
+params.Offset = 0
+params.NSFW = false
+params.Fields = []string{}
+
+err := client.GetAnimeRanking(&rankingList, params)
+if err != nil {
+ fmt.Println(err)
+}
+
+// ...
+```
+
+## Get any user's manga list
+
+`MainAuth` or `ClientAuth`
+
+This returns a boolean telling us if there is a next page on this user's list.
+Simply increment the offset by the limit and create a new request in order to get the next page.
+
+In order to get the complete list, repeat the process until `nextPageExists` becomes false.
+
+Accepted statuses:
+- `mg.ListStatusAll`
+- `mg.ListStatusReading`
+- `mg.ListStatusCompleted`
+- `mg.ListStatusOnHold`
+- `mg.ListStatusDropped`
+- `mg.ListStatusPTR`
+
+Accepted list sorts:
+- `mg.SortByListScore` (descending)
+- `mg.SortByListUpdatedAt` (descending)
+- `mg.SortByMangaTitle` (ascending)
+- `mg.SortByMangaStartDate` (descending)
+- `mg.SortByMangaId` (ascending) (beta according to MAL)
+
+``` go
+// ...
+
+var mangas []mg.Manga
+
+params := mg.ListParamsNew()
+
+// optional; these are the default values
+params.Username = "@me" // can speciy any public account
+params.Status = mg.ListStatusAll
+params.Sort = mg.SortByListScore
+params.Limit = 100 // max = 1000
+params.Offset = 0
+params.NSFW = false
+params.Fields = []string{}
+
+nextPageExists, err := client.GetMangaList(&mangas, params)
+if err != nil {
+ fmt.Println(err)
+}
+
+// ...
+```
+
+## Updating a manga
+
+`MainAuth` only
+
+Updates a manga in the the currently logged in user's manga list.
+Adds the manga if it's not in the list.
+
+Accepted statuses:
+- `mg.ListStatusReading`
+- `mg.ListStatusCompleted`
+- `mg.ListStatusOnHold`
+- `mg.ListStatusDropped`
+- `mg.ListStatusPTR`
+
+Score range: `0` - `10`
+
+Priority range: `0` - `2`
+| Priority | Description |
+|----------|-------------|
+| 0 | Low |
+| 1 | Medium |
+| 2 | High |
+
+RereadValue range: `0` - `5`
+| RereadValue | Description |
+|-------------|-------------|
+| 0 | None |
+| 1 | Very Low |
+| 2 | Low |
+| 3 | Medium |
+| 4 | High |
+| 5 | Very High |
+
+``` go
+// ...
+
+var res MangaUpdateResponse
+
+// can omit any field but keep at least 1!
+params := map[string]interface{} {
+ mg.Status: mg.ListStatusReading,
+ mg.IsRereading: false,
+ mg.Score: 10,
+ mg.VolumesRead: 2,
+ mg.ChaptersRead: 20,
+ mg.Priority: 2,
+ mg.TimesReread: 0,
+ mg.RereadValue: 5,
+ mg.Tags: "tags",
+ mg.Comments: "comments",
+}
+
+err := client.UpdateManga(&res, /*manga id*/ 55215, params)
+if err != nil {
+ fmt.Println(err)
+}
+
+// ...
+```
+
+## Deleting a manga from list
+
+`MainAuth` only
+
+Deletes the manga from currently logged in user's manga list.
+Returns an error if manga is already not in the list.
+
+``` go
+// ...
+
+err := client.DeleteManga(/*manga id*/ 55215)
+if err != nil {
+ fmt.Println(err)
+}
+
+// ...
+```
+
+# User
+
+## Get logged in user's details
+
+`MainAuth` only
+
+MyAnimeList's official API doesn't support getting another user's details. Only the currently logged in user.
+
+``` go
+// ...
+
+var user mg.User
+
+// to get user's list statistics or not
+getStatistics := true
+
+err := client.GetSelfInfo(&user, getStatistics)
+if err != nil {
+ fmt.Println(err)
+}
+
+// ...
+```