myanimelist

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 26, 2020 License: MIT Imports: 12 Imported by: 0

README

MyAnimeList-Go

PkgGoDev Build Status Go Report Card

MyAnimeList-Go is a small library to simplify your usage of MyAnimeList' API

According to official API documentation, current version of API labeled as Beta. Considering this, MyAnimeList-Go can't be called Stable too. But still, at this moment library fully covers all available methods of current API version (v2.0.0).

Table of contents

click to open

Installation

Library was tested to be working at v1.7+, but it is recommended to use v1.11+

import "github.com/camelva/myanimelist-go"  

Preparing

Before using API you need to obtain your MyAnimeList client's ID and Secret keys first. It can be achieved by creating new Application. For this, simply head to Settings => API. Or just use this link. Then, click on Create ID button and fill required fields.
After that, you can find Client ID and Client Secret fields inside your newly created app. Copy them to safe place - we will need them soon.

MyAnimeList Application info

Usage

Creating instance

To create new instance you just need to pass Config structure to myanimelist.New(). Example code below:

package main

import (
	"github.com/camelva/myanimelist-go"
	"log"
	"net/http"
	"time"
)

func main() {
	config := myanimelist.Config{
		ClientID: "clientid",
		ClientSecret: "clientsecret",
		RedirectURL: "https://example.com/anime/callback",
		// Optional
		// HTTPClient: *http.Client{Timeout: 5 * time.Second}
		// Logger: *log.Logger{}
	}
	mal, err := myanimelist.New(config)
	if err != nil {
		log.Fatal(err)
	}
	// do stuff
}

Here you use Client ID and Client Secret, obtained on previous step.
Also make sure you added your Redirect URL to MyAnimeList' application settings, otherwise it will not work.

Reference: New()


Authorization

Every method of API requires user's Access Token, so its good idea to auth as soon as possible.
MyAnimeList uses OAuth2, so whole process consist of 2 steps: heading user to MyAnimeList's Login page and exchanging received temporaty token for long-term access token.

Reference: Auth.LoginURL() | Auth.ExchangeToken()

Example code:

package main

import (
	"github.com/camelva/myanimelist-go"
	"log"
	"net/http"
)

// imagine we already made initialization
var mal = &myanimelist.MAL{}

func main() {
	http.HandleFunc("/login", loginHandler)
	http.HandleFunc("/callback", callbackHandler)
	http.HandleFunc("/app", appHandler)

	log.Fatal(http.ListenAndServe(":3000", nil))
}

// Step 1: Heading user to MyAnimeList login page
func loginHandler(w http.ResponseWriter, req *http.Request) {
	// creating authorization URL
	loginPageURL := mal.Auth.LoginURL()
	// and redirecting user there
	http.Redirect(w, req, loginPageURL, http.StatusFound)
}

// Step 2: Exchanging tokens
func callbackHandler(w http.ResponseWriter, req *http.Request) {
	// gathering temporary code from request query
	code := req.FormValue("code")
	// and exchange it for long-lasting access token
	userInfo, err := mal.Auth.ExchangeToken(code)
	if err != nil {
		// handle error
		return
	}
	// optionally you can store tokens in your db or anywhere else
	_, _, _ = userInfo.AccessToken, userInfo.ExpireAt, userInfo.RefreshToken
	http.Redirect(w, req, "/app", http.StatusFound)
}

func appHandler(w http.ResponseWriter, req *http.Request) {
	if mal.Auth.GetTokenInfo().AccessToken == "" {
		http.Redirect(w, req, "/login", http.StatusFound)
	}
	// do some stuff
}
Token expiration

Every user's access tokens have certain time they are valid. Standard, its 1 month (31 day) . You can always check when token will expire by reading ExpireAt field of UserCredentials.
If token already expired - you need to ask user to do authorization steps again. But if token still valid - you can request token update and receive new token with fresh duration without even user's interaction. For this, just call mal.Auth.RefreshToken():

newCredentials, err := mal.Auth.RefreshToken()  

Reference: Auth.RefreshToken()


Get tokens

You can get your current user's tokens by running:

mal.Auth.GetTokenInfo()

Reference: Auth.GetTokenInfo()


Set tokens manually

If you have your user's tokens saved somewhere and want to continue session without forcing user to log in again - you can set tokens manually.

mal.Auth.SetTokenInfo(accessToken string, refreshToken string, expireAt time.Time)

Reference: Auth.SetTokenInfo()


Search anime (manga)

Searching is simple - just use mal.Anime.Search or mal.Manga.Searchwith your query string and PagingSettings as parameters. These requests are multi-paged, so look at Multiple pages for additional info.

Reference: Anime.Search() | Manga.Search()


Details about certain anime (manga)

For retrieving detailed info there are mal.Anime.Details and mal.Manga.Details methods. Both accepts ID as first parameter, and, optionally, names of fields to gather. By default, these methods returns AnimeDetails (or MangaDetails) struct with fields ID, Title and MainPicture. To acquire more fields - you need to explicitly specify them by yourself. You can find list of all Shared, Anime-only and Manga-only fields at Constants

Reference: Anime.Details() | Manga.Details()


Top anime (manga)

Use mal.Anime.Top or mal.Manga.Top. First parameter is RankingType, second - PagingSettings (for more info about paged results see Multiple pages). There are a couple of different ranks at MyAnimeList, you can find all of them at the official documentation - Anime ranks and Manga ranks or at library's documentation constants section.

Reference: Anime.Top() | Manga.Top()


Seasonal anime

You can get anime list of certain year's season by running

mal.Anime.Seasonal(year int, season string, sort string, settings PagingSettings)

Only year and season parameters are required, rest are optional. For season use one of these constants: SeasonWinter, SeasonSpring, SeasonSummer or SeasonFall. By passing non-zero sort parameter, you can sort result by score or number of users, added anime to their list. For this, use either SortByScore or SortByUsersLists constants. For additional info about PagingSettings see Multiple pages

Reference: Anime.Seasonal()


Anime suggestions

Get anime suggestions for current user by running:

mal.Anime.Suggestions(setting PagingSettings)

For additional info about PagingSettings see Multiple pages

Reference: Anime.Suggestions()


User information

At the moment, you can acquire information only about current user (but seems like this API method will support different usernames too)

mal.User.Info(settings PagingSetting)

For additional info about PagingSettings see Multiple pages

Reference: User.Info()


User anime (manga) list
mal.Anime.List.User(username string, status string, sort string, settings PagingSettings)
mal.Manga.List.User(username string, status string, sort string, settings PagingSettings)

Here you can use any username to request their anime/manga list. To get current user - pass empty string. By passing status you can filter response to contain only entries with same status. You can look at library documentation's constants section to find all Shared Statuses, Anime-only and Manga-only Also you can sort result by passing corresponding parameter. List of all available sort constants can also be found at documentation For additional info about PagingSettings see Multiple pages.

Reference: AnimeList.User() | MangaList.User()


Update anime (manga) status

To add entry to your list or update their statuses you should use corresponding methods:

mal.Anime.List.Update(config AnimeConfig)
mal.Manga.List.Update(config MangaConfig)

Reference: AnimeList.Update() | MangaList.Update()

Both of them require appropriate config struct. It's recommended to create them by running NewAnimeConfig(id int) (NewMangaConfig(id int)). These config structures have a bunch of helper methods to set values you want to change. Such as SetScore, SetStatus and so on. For list of all available methods see documentation reference.

Reference: AnimeConfig | MangaConfig


Remove entry from list

To remove anime from your list use mal.Anime.List.Remove(id int) or mal.Manga.List.Remove(id int) for manga. If there is no entry with such id in your list - call still considered as successful and returns no error.

Reference: AnimeList.Remove() | MangaList.Remove()


Forum
Forum boards
mal.Forum.Boards()

Returns information about all forum categories, boards and sub-boards

Reference: Forum.Boards()


Forum search provided by

mal.Forum.Search(searchOpts ForumSearchSettings, settings PagingSettings)

ForumSearchSettings contain all your search parameters. There is no required fields, but you need to fill at least one of them. See documentation for additional info. For additional info about PagingSettings see Multiple pages.

Reference: Forum.Search() | ForumSearchSettings


Forum topic information

To acquire information about certain topic use:

mal.Forum.Topic(id int, settings PagingSettings)

For additional info about PagingSettings see Multiple pages

Reference: Forum.Topic()

Multiple pages

Some requests (such as Anime.Top()) returns a lot of data, so result split into multiple pages.
You can detect such functions by having a special input parameter - struct PagingSettings with two fields: limit and offset (of course you can specify only field you need, or even leave both at zero).
These functions' returned value (let's call it PagedResult) is always struct with, among other things, field Paging. This field contains URLs to next and previous pages accordingly. So, for simplified usage, every of such PagedResult structures have Next and Prev methods. Which optionally accepts new limit value as parameters.

Example usage:

package main

import (
	"github.com/camelva/myanimelist-go"
)

// imagine we already made initialization
var mal = &myanimelist.MAL{}

func main() {
	// lets request 10 top anime, ranked by popularity
	popularAnime, err := mal.Anime.Top(
		myanimelist.RankByPopularity,
		myanimelist.PagingSettings{Limit: 10})
	if err != nil {
		panic(err) // example error handling
	}
    // showed result to user or something else
    // but now we want to get another 10 top anime
    morePopularAnime, err := popularAnime.Next()
    if err != nil {
    	panic(err) // example error handling
    }
    // and now we want more, but only 5
    anotherPopularAnime, err := morePopularAnime.Next(5)
    if err != nil {
    	panic(err) // example error handling
    }
    _ = anotherPopularAnime // do something with result
}  

Contributing

  1. Fork it (https://github.com/Camelva/myanimelist-go/fork)
  2. Create your feature branch (git checkout -b feature/fooBar)
  3. Commit your changes (git commit -am 'Add some fooBar')
  4. Push to the branch (git push origin feature/fooBar)
  5. Create a new Pull Request

References

Documentation

Overview

myanimelist is a small library to simplify usege of MyAnimeList's API

Index

Constants

View Source
const (
	FieldID                string = "id"
	FieldTitle             string = "title"
	FieldMainPicture       string = "main_picture"
	FieldAlternativeTitles string = "alternative_titles"
	FieldStartDate         string = "start_date"
	FieldEndDate           string = "end_date"
	FieldSynopsis          string = "synopsis"
	FieldMean              string = "mean"
	FieldRank              string = "rank"
	FieldPopularity        string = "popularity"
	FieldNumListUsers      string = "num_list_users"
	FieldNumScoringUsers   string = "num_scoring_users"
	FieldNSFW              string = "nsfw"
	FieldCreatedAt         string = "created_at"
	FieldUpdatedAt         string = "updated_at"
	FieldMediaType         string = "media_type"
	FieldStatus            string = "status"
	FieldGenres            string = "genres"
	FieldMyListStatus      string = "my_list_status"
	FieldPictures          string = "pictures"
	FieldBackground        string = "background"
	FieldRelatedAnime      string = "related_anime"
	FieldRelatedManga      string = "related_manga"
	FieldRecommendations   string = "recommendations"
	FieldStudios           string = "studios"
	FieldStatistics        string = "statistics"
)

Shared fields for both Anime.Details() and Manga.Details().

View Source
const (
	FieldNumEpisodes            string = "num_episodes"
	FieldStartSeason            string = "start_season"
	FieldBroadcast              string = "broadcast"
	FieldSource                 string = "source"
	FieldAverageEpisodeDuration string = "average_episode_duration"
	FieldRating                 string = "rating"
)

Anime.Details() only fields

View Source
const (
	FieldNumVolumes    string = "num_volumes"
	FieldNumChapters   string = "num_chapters"
	FieldAuthors       string = "authors{first_name,last_name}"
	FieldSerialization string = "serialization{name}"
)

Manga.Details() only fields.

View Source
const (
	// Top Anime|Manga Series
	RankAll string = "all"
	// Top Anime|Manga by Popularity
	RankByPopularity string = "bypopularity"
	// Top Anime|Manga by Favorite
	RankFavorite string = "favorite"
)

Shared ranks for both Anime.Top() and Manga.Top().

View Source
const (
	// Top Airing Anime
	RankAiring string = "airing"
	// Top Upcoming Anime
	RankUpcoming string = "upcoming"
	// Top Anime TV Series
	RankTV string = "tv"
	// Top Anime OVA Series
	RankOVA string = "ova"
	// Top Anime Movies
	RankMovie string = "movie"
	// Top Anime Specials
	RankSpecials string = "special"
)

Anime.Top() only

View Source
const (
	// Top Manga
	RankManga string = "manga"
	// Top Novels
	RankNovels string = "novels"
	// Top One-shots
	RankOneShots string = "oneshots"
	// Top Doujinshi
	RankDoujinshi string = "doujin"
	// Top Manhwa
	RankManhwa string = "manhwa"
	// Top Manhua
	RankManhua string = "manhua"
)

Manga.Top() only

View Source
const (
	StatusOnHold    string = "on_hold"
	StatusDropped   string = "dropped"
	StatusCompleted string = "completed"
)

Shared statuses, working for Anime.List.User() && Manga.List.User() and for AnimeConfig.SetStatus() && MangaConfig.SetStatus() too.

View Source
const (
	StatusWatching    string = "watching"
	StatusPlanToWatch string = "plan_to_watch"
)

Anime-only statuses (Anime.List.User() and AnimeConfig.SetStatus())

View Source
const (
	StatusReading    string = "reading"
	StatusPlanToRead string = "plan_to_read"
)

Manga-only statuses (Manga.List.User() and MangaConfig.SetStatus())

View Source
const (
	// January, February, March
	SeasonWinter string = "winter"
	// April, May, June
	SeasonSpring string = "spring"
	// July, August, September
	SeasonSummer string = "summer"
	// October, November, December
	SeasonFall string = "fall"
)

Predefined season values. Used for 'Anime.Seasonal()'

View Source
const (
	SortByScore      string = "anime_score"
	SortByUsersLists string = "anime_num_list_users"
)

Used to sort Anime.Seasonal() response

View Source
const (
	PriorityLow = iota
	PriorityMedium
	PriorityHigh
)

Anime or manga priority. Used with AnimeConfig.SetPriority() and MangaConfig.SetPriority()

View Source
const (
	SortListByScore      string = "list_score"
	SortListByUpdateDate string = "list_updated_at"
	SortListByTitle      string = "title"
	SortListByStartDate  string = "start_date"
	SortListByID         string = "id"
)

User list's sort

View Source
const FieldAllAvailable string = "*"

Custom field, applicable to both Anime.Details() and Manga.Details(). Transforms into all available fields before sending request.

Variables

This section is empty.

Functions

This section is empty.

Types

type Anime

type Anime struct {
	List AnimeList
	// contains filtered or unexported fields
}

func (*Anime) Details

func (a *Anime) Details(animeID int, fields ...string) (*AnimeDetails, error)

AnimeDetails returns details about anime with provided ID. You can control which fields to retrieve. For all fields use FieldAllAvailable. With no fields provided api still returns ID, Title and MainPicture fields

func (*Anime) Search

func (a *Anime) Search(search string, settings PagingSettings) (*AnimeSearchResult, error)

AnimeSearch return list of anime, performing search for similar as provided search string.

func (*Anime) Seasonal

func (a *Anime) Seasonal(year int, season string, sort string, settings PagingSettings) (*AnimeSeasonal, error)

SeasonalAnime returns list of anime from certain year's season. Season are required. Rest fields are optional. For additional info see https://myanimelist.net/apiconfig/references/api/v2#operation/anime_ranking_get

func (*Anime) Suggestions

func (a *Anime) Suggestions(settings PagingSettings) (*AnimeSuggestions, error)

SuggestedAnime returns suggested anime for the authorized user. If the user is new comer, expect to receive empty result.

func (*Anime) Top

func (a *Anime) Top(rankingType string, settings PagingSettings) (*AnimeTop, error)

AnimeTop returns list of top anime, for each measurement. For additional info, see: https://myanimelist.net/apiconfig/references/api/v2#operation/anime_ranking_get Currently available ranks: - RankAll, - RankAiring, - RankUpcoming, - RankTV, - RankOVA, - RankMovie, - RankSpecial, - RankByPopularity, - RankFavorite.

type AnimeConfig

type AnimeConfig map[string]string

AnimeConfig contains all the changes you want to apply

func NewAnimeConfig

func NewAnimeConfig(id int) AnimeConfig

NewAnimeConfig generates new config and sets anime id You can also manually create object and set id with SetID(id int) method

func (AnimeConfig) SetComment

func (c AnimeConfig) SetComment(text string) AnimeConfig

func (AnimeConfig) SetID

func (c AnimeConfig) SetID(id int) AnimeConfig

func (AnimeConfig) SetIsRewatching

func (c AnimeConfig) SetIsRewatching(b bool) AnimeConfig

func (AnimeConfig) SetPriority

func (c AnimeConfig) SetPriority(priority int) AnimeConfig

SetPriority accept only PriorityLow, PriorityMedium or PriorityHigh constants

func (AnimeConfig) SetRewatchValue

func (c AnimeConfig) SetRewatchValue(value int) AnimeConfig

func (AnimeConfig) SetRewatchedTimes

func (c AnimeConfig) SetRewatchedTimes(count int) AnimeConfig

func (AnimeConfig) SetScore

func (c AnimeConfig) SetScore(score int) AnimeConfig

func (AnimeConfig) SetStatus

func (c AnimeConfig) SetStatus(status string) AnimeConfig

SetStatus accept only StatusWatching, StatusCompleted, StatusOnHold, StatusDropped or StatusPlanToWatch constants

func (AnimeConfig) SetTags

func (c AnimeConfig) SetTags(tags ...string) AnimeConfig

func (AnimeConfig) SetWatchedEpisodes

func (c AnimeConfig) SetWatchedEpisodes(count int) AnimeConfig

type AnimeDetails

type AnimeDetails struct {
	ID                int     `json:"id"`
	Title             string  `json:"title"`
	MainPicture       Picture `json:"main_picture"`
	AlternativeTitles struct {
		Synonyms []string `json:"synonyms"`
		En       string   `json:"en"`
		Ja       string   `json:"ja"`
	} `json:"alternative_titles"`
	StartDate       string          `json:"start_date"`
	EndDate         string          `json:"end_date"`
	Synopsis        string          `json:"synopsis"`
	Mean            float64         `json:"mean"`
	Rank            int             `json:"rank"`
	Popularity      int             `json:"popularity"`
	NumListUsers    int             `json:"num_list_users"`
	NumScoringUsers int             `json:"num_scoring_users"`
	Nsfw            string          `json:"nsfw"`
	CreatedAt       time.Time       `json:"created_at"`
	UpdatedAt       time.Time       `json:"updated_at"`
	MediaType       string          `json:"media_type"`
	Status          string          `json:"status"`
	Genres          []Genre         `json:"genres"`
	MyListStatus    AnimeListStatus `json:"my_list_status"`
	NumEpisodes     int             `json:"num_episodes"`
	StartSeason     struct {
		Year   int    `json:"year"`
		Season string `json:"season"`
	} `json:"start_season"`
	Broadcast struct {
		DayOfTheWeek string `json:"day_of_the_week"`
		StartTime    string `json:"start_time"`
	} `json:"broadcast"`
	Source                 string    `json:"source"`
	AverageEpisodeDuration int       `json:"average_episode_duration"`
	Rating                 string    `json:"rating"`
	Pictures               []Picture `json:"pictures"`
	Background             string    `json:"background"`
	RelatedAnime           []struct {
		Node                  `json:"node"`
		RelationType          string `json:"relation_type"`
		RelationTypeFormatted string `json:"relation_type_formatted"`
	} `json:"related_anime"`
	RelatedManga []struct {
		Node                  `json:"node"`
		RelationType          string `json:"relation_type"`
		RelationTypeFormatted string `json:"relation_type_formatted"`
	} `json:"related_manga"`
	Recommendations []struct {
		Node               `json:"node"`
		NumRecommendations int `json:"num_recommendations"`
	} `json:"recommendations"`
	Studios []struct {
		ID   int    `json:"id"`
		Name string `json:"name"`
	} `json:"studios"`
	Statistics struct {
		Status struct {
			Watching    string `json:"watching"`
			Completed   string `json:"completed"`
			OnHold      string `json:"on_hold"`
			Dropped     string `json:"dropped"`
			PlanToWatch string `json:"plan_to_watch"`
		} `json:"status"`
		NumListUsers int `json:"num_list_users"`
	} `json:"statistics"`
}

AnimeDetails contain info about certain anime.

type AnimeList

type AnimeList struct {
	// contains filtered or unexported fields
}

func (*AnimeList) Remove

func (al *AnimeList) Remove(animeID int) error

DeleteAnimeFromList remove entry with certain ID from current user's list. If the specified entry does not exist in user's list, function acts like call was successful and returns nil

func (*AnimeList) Update

func (al *AnimeList) Update(config AnimeConfig) (*AnimeStatus, error)

UpdateAnimeStatus changes specified anime' properties according to provided AnimeConfig. Returns updated AnimeStatus or error, if any.

func (*AnimeList) User

func (al *AnimeList) User(username string, status string, sort string, settings PagingSettings) (*UserAnimeList, error)

UserAnimeList returns anime list of certain user with provided username (for current user use empty string). You can set status to retrieve only anime's with same status or use empty object. You can sort list by using on of these constants: SortListByScore, SortListByUpdateDate, SortListByTitle, SortListByStartDate, SortListByID or provide empty object to disable sorting

type AnimeListStatus

type AnimeListStatus struct {
	Status             string    `json:"status"`
	Score              int       `json:"score"`
	NumWatchedEpisodes int       `json:"num_watched_episodes"`
	IsRewatching       bool      `json:"is_rewatching"`
	UpdatedAt          time.Time `json:"updated_at"`
}

type AnimeSearchResult

type AnimeSearchResult struct {
	Data []struct {
		Node `json:"node"`
	} `json:"data"`
	Paging Paging `json:"paging"`
	// contains filtered or unexported fields
}

AnimeSearchResult stores array with search entries. Use Prev() and Next() methods to retrieve corresponding result pages.

func (*AnimeSearchResult) Next

func (obj *AnimeSearchResult) Next(limit ...int) (result *AnimeSearchResult, err error)

Next return next result page. If its last page - returns error.

func (*AnimeSearchResult) Prev

func (obj *AnimeSearchResult) Prev(limit ...int) (result *AnimeSearchResult, err error)

Prev return previous result page. If its first page - returns error.

type AnimeSeasonal

type AnimeSeasonal struct {
	Data []struct {
		Node `json:"node"`
	} `json:"data"`
	Paging Paging `json:"paging"`
	Season struct {
		Year   int    `json:"year"`
		Season string `json:"season"`
	} `json:"season"`
	// contains filtered or unexported fields
}

AnimeSeasonal contain array with basic anime nodes (ID, Title, MainPicture). Use Prev() and Next() methods to retrieve corresponding result pages.

func (*AnimeSeasonal) Next

func (obj *AnimeSeasonal) Next(limit ...int) (result *AnimeSeasonal, err error)

Next return next result page. If its last page - returns error.

func (*AnimeSeasonal) Prev

func (obj *AnimeSeasonal) Prev(limit ...int) (result *AnimeSeasonal, err error)

Prev return previous result page. If its first page - returns error.

type AnimeStatistics

type AnimeStatistics struct {
	NumItemsWatching    int     `json:"num_items_watching"`
	NumItemsCompleted   int     `json:"num_items_completed"`
	NumItemsOnHold      int     `json:"num_items_on_hold"`
	NumItemsDropped     int     `json:"num_items_dropped"`
	NumItemsPlanToWatch int     `json:"num_items_plan_to_watch"`
	NumItems            int     `json:"num_items"`
	NumDaysWatched      float64 `json:"num_days_watched"`
	NumDaysWatching     float64 `json:"num_days_watching"`
	NumDaysCompleted    float64 `json:"num_days_completed"`
	NumDaysOnHold       float64 `json:"num_days_on_hold"`
	NumDaysDropped      float64 `json:"num_days_dropped"`
	NumDays             float64 `json:"num_days"`
	NumEpisodes         int     `json:"num_episodes"`
	NumTimesRewatched   int     `json:"num_times_rewatched"`
	MeanScore           float64 `json:"mean_score"`
}

type AnimeStatus

type AnimeStatus struct {
	Status             string    `json:"status"`
	Score              int       `json:"score"`
	NumWatchedEpisodes int       `json:"num_episodes_watched"`
	IsRewatching       bool      `json:"is_rewatching"`
	UpdatedAt          time.Time `json:"updated_at"`
	Priority           int       `json:"priority"`
	NumTimesRewatched  int       `json:"num_times_rewatched"`
	RewatchValue       int       `json:"rewatch_value"`
	Tags               []string  `json:"tags"`
	Comments           string    `json:"comments"`
}

AnimeStatus contains server response about certain anime

type AnimeSuggestions

type AnimeSuggestions struct {
	Data []struct {
		Node `json:"node"`
	} `json:"data"`
	Paging Paging `json:"paging"`
	// contains filtered or unexported fields
}

SuggestedAnime contain arrays of anime Nodes (ID, Title, MainPicture), suggested for current user. Use Prev() and Next() methods to retrieve corresponding result pages.

func (*AnimeSuggestions) Next

func (obj *AnimeSuggestions) Next(limit ...int) (result *AnimeSuggestions, err error)

Next return next result page. If its last page - returns error.

func (*AnimeSuggestions) Prev

func (obj *AnimeSuggestions) Prev(limit ...int) (result *AnimeSuggestions, err error)

Prev return previous result page. If its first page - returns error.

type AnimeTop

type AnimeTop struct {
	Data []struct {
		Node    `json:"node"`
		Ranking struct {
			Rank int `json:"rank"`
		} `json:"ranking"`
	} `json:"data"`
	Paging Paging `json:"paging"`
	// contains filtered or unexported fields
}

AnimeTop contain arrays of Nodes (ID, Title, MainPicture) with their rank position. Use Prev() and Next() methods to retrieve corresponding result pages.

func (*AnimeTop) Next

func (obj *AnimeTop) Next(limit ...int) (result *AnimeTop, err error)

Next return next result page. If its last page - returns error.

func (*AnimeTop) Prev

func (obj *AnimeTop) Prev(limit ...int) (result *AnimeTop, err error)

Prev return previous result page. If its first page - returns error.

type Auth

type Auth struct {
	// contains filtered or unexported fields
}

Auth contain all authorization-related data

func (*Auth) ExchangeToken

func (a *Auth) ExchangeToken(authCode string) (*UserCredentials, error)

RetrieveToken use received from user's authorization code and send it to server to receive user access token

func (*Auth) GetTokenInfo

func (a *Auth) GetTokenInfo() *UserCredentials

GetTokenInfo returns all required user's credentials: access token, refresh token and access token's expiration date.

func (*Auth) LoginURL

func (a *Auth) LoginURL() string

LoginURL starts OAuth process and return login URL. For additional info use this: https://myanimelist.net/apiconfig/references/authorization.

func (*Auth) RefreshToken

func (a *Auth) RefreshToken() (*UserCredentials, error)

func (*Auth) SetTokenInfo

func (a *Auth) SetTokenInfo(accessToken string, refreshToken string, expire time.Time)

SetTokenInfo completely rewrites saved user's credentials, so use it very careful. In case you erased correct tokens - lead user to authorization page again.

type Config

type Config struct {
	ClientID     string
	ClientSecret string
	RedirectURL  string
	HTTPClient   *http.Client
	Logger       *log.Logger
}

Config stores important data to create new MyAnimeList client. HTTPClient and Logger is optional.

type Forum

type Forum struct {
	// contains filtered or unexported fields
}

func (*Forum) Boards

func (f *Forum) Boards() (*ForumCategories, error)

ForumBoards return list of all forum's categories.

func (*Forum) Search

func (f *Forum) Search(searchOpts ForumSearchSettings, settings PagingSettings) (*ForumSearchResult, error)

ForumSearchTopics implements advanced search from website. Use ForumSearchSettings struct to set search options.

func (*Forum) Topic

func (f *Forum) Topic(topicID int, settings PagingSettings) (*ForumTopic, error)

ForumTopic retrieves info about topic with provided topicID.

type ForumBoard

type ForumBoard struct {
	ID          int             `json:"id"`
	Title       string          `json:"title"`
	Description string          `json:"description"`
	SubBoards   []ForumSubBoard `json:"subboards"`
}

type ForumCategories

type ForumCategories struct {
	Categories []ForumCategory `json:"categories"`
}

ForumCategories stores data received from executing ForumBoards()

type ForumCategory

type ForumCategory struct {
	Title  string       `json:"title"`
	Boards []ForumBoard `json:"boards"`
}

type ForumPost

type ForumPost struct {
	ID        int                 `json:"id"`
	Number    int                 `json:"number"`
	CreatedAt time.Time           `json:"created_at"`
	CreatedBy ForumUserWithAvatar `json:"created_by"`
	Body      string              `json:"body"`
	Signature string              `json:"signature"`
}

type ForumSearchEntry

type ForumSearchEntry struct {
	ID                int       `json:"id"`
	Title             string    `json:"title"`
	CreatedAt         time.Time `json:"created_at"`
	CreatedBy         ForumUser `json:"created_by"`
	NumberOfPosts     int       `json:"number_of_posts"`
	LastPostCreatedAt time.Time `json:"last_post_created_at"`
	LastPostCreatedBy ForumUser `json:"last_post_created_by"`
	IsLocked          bool      `json:"is_locked"`
}

type ForumSearchResult

type ForumSearchResult struct {
	Data   []ForumSearchEntry `json:"data"`
	Paging Paging             `json:"paging"`
	// contains filtered or unexported fields
}

ForumSearchResult stores array with search result entries. Use Prev() and Next() methods to retrieve corresponding result pages.

func (*ForumSearchResult) Next

func (obj *ForumSearchResult) Next(limit ...int) (result *ForumSearchResult, err error)

Next return next result page. If its last page - returns error.

func (*ForumSearchResult) Prev

func (obj *ForumSearchResult) Prev(limit ...int) (result *ForumSearchResult, err error)

Prev return previous result page. If its first page - returns error.

type ForumSearchSettings

type ForumSearchSettings struct {
	Keyword      string
	BoardID      int
	SubboardID   int
	TopicStarter string
	PostAuthor   string
}

ForumSearchSetting represent advanced search on MyAnimeList forum. All fields are optional.

type ForumSubBoard

type ForumSubBoard struct {
	ID    int    `json:"id"`
	Title string `json:"title"`
}

type ForumTopic

type ForumTopic struct {
	Data struct {
		Title string      `json:"title"`
		Posts []ForumPost `json:"posts"`
		Poll  Poll        `json:"poll"`
	} `json:"data"`
	Paging Paging `json:"paging"`
	// contains filtered or unexported fields
}

ForumTopic stores topic title, poll, array of posts. Use Prev() and Next() methods to retrieve corresponding result pages.

func (*ForumTopic) Next

func (obj *ForumTopic) Next(limit ...int) (result *ForumTopic, err error)

Next return next result page. If its last page - returns error.

func (*ForumTopic) Prev

func (obj *ForumTopic) Prev(limit ...int) (result *ForumTopic, err error)

Prev return previous result page. If its first page - returns error.

type ForumUser

type ForumUser struct {
	ID   int    `json:"id"`
	Name string `json:"name"`
}

type ForumUserWithAvatar

type ForumUserWithAvatar struct {
	ID     int    `json:"id"`
	Name   string `json:"name"`
	Avatar string `json:"forum_avator"`
}

type Genre

type Genre struct {
	ID   int    `json:"id"`
	Name string `json:"name"`
}

type MAL

type MAL struct {

	// Auth contain all authorization-related data
	Auth Auth

	Anime Anime
	Manga Manga
	Forum Forum
	User  User
	// contains filtered or unexported fields
}

func New

func New(config Config) (*MAL, error)

New creates new MyAnimeList client with specified parameters. Every api method require authorization so you need to provide all auth-related data before client's initialisation. If you plan to set user's tokens manually with SetTokenInfo(), instead of authorization - you can specify "/" as redirect URL.

type Manga

type Manga struct {
	List MangaList
	// contains filtered or unexported fields
}

func (*Manga) Details

func (m *Manga) Details(mangaID int, fields ...string) (*MangaDetails, error)

MangaDetails returns details about manga with provided ID. You can control which fields to retrieve. For all fields use FieldAllAvailable. With no fields provided api still returns ID, Title and MainPicture fields

func (*Manga) Search

func (m *Manga) Search(search string, settings PagingSettings) (*MangaSearchResult, error)

MangaSearch return list of manga, performing search for similar as provided search string.

func (*Manga) Top

func (m *Manga) Top(rankingType string, settings PagingSettings) (*MangaTop, error)

MangaRanking returns list of top manga, for each measurement. For additional info, see: https://myanimelist.net/apiconfig/references/api/v2#operation/manga_ranking_get Currently available ranks: - RankAll, - RankManga, - RankNovels, - RankOneShots, - RankDoujinshi, - RankManhwa, - RankManhua, - RankByPopularity, - RankFavorite.

type MangaConfig

type MangaConfig map[string]string

MangaConfig contains all the changes you want to apply

func NewMangaConfig

func NewMangaConfig(id int) MangaConfig

NewMangaConfig generates new config and sets manga id You can also manually create object and set id with SetID(id int) method

func (MangaConfig) SetChaptersRead

func (c MangaConfig) SetChaptersRead(num int) MangaConfig

func (MangaConfig) SetComment

func (c MangaConfig) SetComment(text string) MangaConfig

func (MangaConfig) SetID

func (c MangaConfig) SetID(id int) MangaConfig

func (MangaConfig) SetIsRereading

func (c MangaConfig) SetIsRereading(b bool) MangaConfig

func (MangaConfig) SetPriority

func (c MangaConfig) SetPriority(priority int) MangaConfig

SetPriority accept only PriorityLow, PriorityMedium or PriorityHigh constants

func (MangaConfig) SetRereadTimes

func (c MangaConfig) SetRereadTimes(count int) MangaConfig

func (MangaConfig) SetRereadValue

func (c MangaConfig) SetRereadValue(value int) MangaConfig

func (MangaConfig) SetScore

func (c MangaConfig) SetScore(score int) MangaConfig

func (MangaConfig) SetStatus

func (c MangaConfig) SetStatus(status string) MangaConfig

SetStatus accept only StatusReading, StatusCompleted, StatusOnHold, StatusDropped or StatusPlanToRead constants

func (MangaConfig) SetTags

func (c MangaConfig) SetTags(tags ...string) MangaConfig

func (MangaConfig) SetVolumesRead

func (c MangaConfig) SetVolumesRead(num int) MangaConfig

type MangaDetails

type MangaDetails struct {
	ID                int     `json:"id"`
	Title             string  `json:"title"`
	MainPicture       Picture `json:"main_picture"`
	AlternativeTitles struct {
		Synonyms []string `json:"synonyms"`
		En       string   `json:"en"`
		Ja       string   `json:"ja"`
	} `json:"alternative_titles"`
	StartDate       string    `json:"start_date"`
	EndDate         string    `json:"end_date"`
	Synopsis        string    `json:"synopsis"`
	Mean            float64   `json:"mean"`
	Rank            int       `json:"rank"`
	Popularity      int       `json:"popularity"`
	NumListUsers    int       `json:"num_list_users"`
	NumScoringUsers int       `json:"num_scoring_users"`
	Nsfw            string    `json:"nsfw"`
	CreatedAt       time.Time `json:"created_at"`
	UpdatedAt       time.Time `json:"updated_at"`
	MediaType       string    `json:"media_type"`
	Status          string    `json:"status"`
	Genres          []Genre   `json:"genres"`
	MyListStatus    struct {
		Status          string    `json:"status"`
		IsRereading     bool      `json:"is_rereading"`
		NumVolumesRead  int       `json:"num_volumes_read"`
		NumChaptersRead int       `json:"num_chapters_read"`
		Score           int       `json:"score"`
		UpdatedAt       time.Time `json:"updated_at"`
	} `json:"my_list_status"`
	NumVolumes  int `json:"num_volumes"`
	NumChapters int `json:"num_chapters"`
	Authors     []struct {
		Node struct {
			ID        int    `json:"id"`
			FirstName string `json:"first_name"`
			LastName  string `json:"last_name"`
		} `json:"node"`
		Role string `json:"role"`
	} `json:"authors"`
	Pictures     []Picture `json:"pictures"`
	Background   string    `json:"background"`
	RelatedAnime []struct {
		Node                  `json:"node"`
		RelationType          string `json:"relation_type"`
		RelationTypeFormatted string `json:"relation_type_formatted"`
	} `json:"related_anime"`
	RelatedManga []struct {
		Node                  `json:"node"`
		RelationType          string `json:"relation_type"`
		RelationTypeFormatted string `json:"relation_type_formatted"`
	} `json:"related_manga"`
	Recommendations []struct {
		Node               `json:"node"`
		NumRecommendations int `json:"num_recommendations"`
	} `json:"recommendations"`
	Serialization []struct {
		Node struct {
			ID   int    `json:"id"`
			Name string `json:"name"`
		} `json:"node"`
	} `json:"serialization"`
}

MangaDetails contain info about certain manga.

type MangaList

type MangaList struct {
	// contains filtered or unexported fields
}

func (*MangaList) Remove

func (ml *MangaList) Remove(animeID int) error

DeleteMangaFromList remove entry with certain ID from current user's list. If the specified entry does not exist in user's list, function acts like call was successful and returns nil

func (*MangaList) Update

func (ml *MangaList) Update(config MangaConfig) (*MangaStatus, error)

UpdateMangaStatus changes specified manga' properties according to provided MangaConfig. Returns updated MangaStatus or error, if any.

func (*MangaList) User

func (ml *MangaList) User(username string, status string, sort string, settings PagingSettings) (*UserMangaList, error)

UserMangaList returns manga list of certain user with provided username You can set status to retrieve only manga's with same status or use empty object You can sort list by using on of these constants: SortListByScore, SortListByUpdateDate, SortListByTitle, SortListByStartDate, SortListByID or provide empty object to disable sorting

type MangaListStatus

type MangaListStatus struct {
	Status          string    `json:"status"`
	Score           int       `json:"score"`
	NumVolumesRead  int       `json:"num_volumes_read"`
	NumChaptersRead int       `json:"num_chapters_read"`
	IsRereading     bool      `json:"is_rereading"`
	UpdatedAt       time.Time `json:"updated_at"`
}

type MangaSearchResult

type MangaSearchResult struct {
	Data []struct {
		Node `json:"node"`
	} `json:"data"`
	Paging Paging `json:"paging"`
	// contains filtered or unexported fields
}

MangaSearchResult stores array with search entries. Use Prev() and Next() methods to retrieve corresponding result pages.

func (*MangaSearchResult) Next

func (obj *MangaSearchResult) Next(limit ...int) (result *MangaSearchResult, err error)

Next return next result page. If its last page - returns error.

func (*MangaSearchResult) Prev

func (obj *MangaSearchResult) Prev(limit ...int) (result *MangaSearchResult, err error)

Prev return previous result page. If its first page - returns error.

type MangaStatus

type MangaStatus struct {
	Status          string    `json:"status"`
	IsRereading     bool      `json:"is_rereading"`
	NumVolumesRead  int       `json:"num_volumes_read"`
	NumChaptersRead int       `json:"num_chapters_read"`
	Score           int       `json:"score"`
	UpdatedAt       time.Time `json:"updated_at"`
	Priority        int       `json:"priority"`
	NumTimesReread  int       `json:"num_times_reread"`
	RereadValue     int       `json:"reread_value"`
	Tags            []string  `json:"tags"`
	Comments        string    `json:"comments"`
}

MangaStatus contains server response about certain manga

type MangaTop

type MangaTop struct {
	Data []struct {
		Node    `json:"node"`
		Ranking struct {
			Rank int `json:"rank"`
		} `json:"ranking"`
	} `json:"data"`
	Paging Paging `json:"paging"`
	// contains filtered or unexported fields
}

MangaRanking contain arrays of Nodes (ID, Title, MainPicture) with their rank position. Use Prev() and Next() methods to retrieve corresponding result pages.

func (*MangaTop) Next

func (obj *MangaTop) Next(limit ...int) (result *MangaTop, err error)

Next return next result page. If its last page - returns error.

func (*MangaTop) Prev

func (obj *MangaTop) Prev(limit ...int) (result *MangaTop, err error)

Prev return previous result page. If its first page - returns error.

type Node

type Node struct {
	ID          int     `json:"id"`
	Title       string  `json:"title"`
	MainPicture Picture `json:"main_picture"`
}

Node type is basic container for anime or manga

type Paging

type Paging struct {
	Previous string `json:"previous"`
	Next     string `json:"next"`
}

type PagingSettings

type PagingSettings struct {
	Limit  int
	Offset int
}

PagingSettings contains limit and offset fields, which are applicable for almost every request. Also, im general, max && default Limit value is 100. But for actual information refer to certain method's official documentation.

type Picture

type Picture struct {
	Medium string `json:"medium"`
	Large  string `json:"large"`
}

type Poll

type Poll struct {
	ID       int          `json:"id"`
	Question string       `json:"question"`
	Closed   bool         `json:"closed"`
	Options  []PollOption `json:"options"`
}

type PollOption

type PollOption struct {
	ID    int    `json:"id"`
	Text  string `json:"text"`
	Votes int    `json:"votes"`
}

type User

type User struct {
	// contains filtered or unexported fields
}

func (*User) Info

func (u *User) Info() (*UserInfo, error)

UserInformation can only retrieve info about current user for now.

type UserAnimeList

type UserAnimeList struct {
	Data []struct {
		Node       `json:"node"`
		ListStatus AnimeListStatus `json:"list_status"`
	} `json:"data"`
	Paging Paging `json:"paging"`
	// contains filtered or unexported fields
}

func (*UserAnimeList) Next

func (obj *UserAnimeList) Next(limit ...int) (result *UserAnimeList, err error)

Next return next result page. If its last page - returns error.

func (*UserAnimeList) Prev

func (obj *UserAnimeList) Prev(limit ...int) (result *UserAnimeList, err error)

Prev return previous result page. If its first page - returns error.

type UserCredentials

type UserCredentials struct {
	AccessToken  string
	RefreshToken string
	ExpireAt     time.Time
}

type UserInfo

type UserInfo struct {
	ID              int             `json:"id"`
	Name            string          `json:"name"`
	Location        string          `json:"location"`
	JoinedAt        time.Time       `json:"joined_at"`
	AnimeStatistics AnimeStatistics `json:"anime_statistics"`
}

type UserMangaList

type UserMangaList struct {
	Data []struct {
		Node       `json:"node"`
		ListStatus MangaListStatus `json:"list_status"`
	} `json:"data"`
	Paging Paging `json:"paging"`
	// contains filtered or unexported fields
}

func (*UserMangaList) Next

func (obj *UserMangaList) Next(limit ...int) (result *UserMangaList, err error)

Next return next result page. If its last page - returns error.

func (*UserMangaList) Prev

func (obj *UserMangaList) Prev(limit ...int) (result *UserMangaList, err error)

Prev return previous result page. If its first page - returns error.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL