From 7b0c78ee356df804d66925d8d8a098dcbdb77fe7 Mon Sep 17 00:00:00 2001 From: Vidhu Kant Sharma Date: Sun, 19 Nov 2023 17:02:29 +0530 Subject: added README.md --- README.md | 565 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 565 insertions(+) create mode 100644 README.md 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 + + + +# 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 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 " + + // or this + client.ClientAuth = "" + 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) +} + +// ... +``` -- cgit v1.2.3