Documentation ¶
Index ¶
- Constants
- func FormatStrings() []string
- type Anilist
- func (a *Anilist) Authorize(ctx context.Context, credentials AnilistLoginCredentials) error
- func (a *Anilist) BindTitleWithID(title string, anilistMangaId int) error
- func (a *Anilist) FindClosestManga(ctx context.Context, title string) (AnilistManga, bool, error)
- func (a *Anilist) GetByID(ctx context.Context, id int) (AnilistManga, bool, error)
- func (a *Anilist) IsAuthorized() bool
- func (a *Anilist) Logout() error
- func (a *Anilist) MakeChapterWithAnilist(ctx context.Context, chapter Chapter) (ChapterOfMangaWithAnilist, bool, error)
- func (a *Anilist) MakeMangaWithAnilist(ctx context.Context, manga Manga) (MangaWithAnilist, bool, error)
- func (a *Anilist) SearchMangas(ctx context.Context, query string) ([]AnilistManga, error)
- func (a *Anilist) SetMangaProgress(ctx context.Context, mangaID, chapterNumber int) error
- type AnilistError
- type AnilistLoginCredentials
- type AnilistManga
- type AnilistOptions
- type Chapter
- type ChapterInfo
- type ChapterOfMangaWithAnilist
- type ChapterWithComicInfoXML
- type Client
- func (c *Client) Anilist() *Anilist
- func (c *Client) ChapterPages(ctx context.Context, chapter Chapter) ([]Page, error)
- func (c *Client) Close() error
- func (c *Client) ComputeChapterFilename(chapter Chapter, format Format) string
- func (c *Client) ComputeMangaFilename(manga Manga) string
- func (c *Client) ComputeVolumeFilename(volume Volume) string
- func (c *Client) DownloadChapter(ctx context.Context, chapter Chapter, options DownloadOptions) (string, error)
- func (c *Client) DownloadPage(ctx context.Context, page Page) (PageWithImage, error)
- func (c *Client) DownloadPagesInBatch(ctx context.Context, pages []Page) ([]PageWithImage, error)
- func (c *Client) FS() afero.Fs
- func (c *Client) Info() ProviderInfo
- func (c *Client) Logger() *Logger
- func (c *Client) MangaVolumes(ctx context.Context, manga Manga) ([]Volume, error)
- func (c *Client) ReadChapter(ctx context.Context, path string, chapter Chapter, options ReadOptions) error
- func (c *Client) SearchMangas(ctx context.Context, query string) ([]Manga, error)
- func (c *Client) String() string
- func (c *Client) VolumeChapters(ctx context.Context, volume Volume) ([]Chapter, error)
- type ClientOptions
- type ComicInfoXML
- type ComicInfoXMLOptions
- type Date
- type DownloadOptions
- type Format
- func (f Format) Extension() string
- func (i Format) IsAFormat() bool
- func (i Format) MarshalJSON() ([]byte, error)
- func (i Format) MarshalText() ([]byte, error)
- func (i Format) MarshalYAML() (interface{}, error)
- func (i Format) String() string
- func (i *Format) UnmarshalJSON(data []byte) error
- func (i *Format) UnmarshalText(text []byte) error
- func (i *Format) UnmarshalYAML(unmarshal func(interface{}) error) error
- type HistoryEntry
- type Logger
- type Manga
- type MangaInfo
- type MangaWithAnilist
- type MangaWithSeriesJSON
- type MetadataError
- type Page
- type PageWithImage
- type Provider
- type ProviderInfo
- type ProviderLoader
- type ReadOptions
- type SeriesJSON
- type Volume
- type VolumeInfo
Constants ¶
const (
UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
)
Variables ¶
This section is empty.
Functions ¶
func FormatStrings ¶
func FormatStrings() []string
FormatStrings returns a slice of all String values of the enum
Types ¶
type Anilist ¶
type Anilist struct {
// contains filtered or unexported fields
}
func NewAnilist ¶
func NewAnilist(options AnilistOptions) Anilist
NewAnilist constructs new Anilist client
func (*Anilist) Authorize ¶ added in v0.6.1
func (a *Anilist) Authorize( ctx context.Context, credentials AnilistLoginCredentials, ) error
Authorize will obtain Anilist token for API requests
func (*Anilist) BindTitleWithID ¶
func (*Anilist) FindClosestManga ¶
func (*Anilist) IsAuthorized ¶
func (*Anilist) MakeChapterWithAnilist ¶
func (*Anilist) MakeMangaWithAnilist ¶
func (*Anilist) SearchMangas ¶
type AnilistError ¶ added in v0.3.0
type AnilistError struct {
// contains filtered or unexported fields
}
func (AnilistError) Error ¶ added in v0.6.1
func (a AnilistError) Error() string
type AnilistLoginCredentials ¶
type AnilistManga ¶
type AnilistManga struct { // Title of the manga Title struct { // Romaji is the romanized title of the manga. Romaji string `json:"romaji" jsonschema:"description=Romanized title of the manga."` // English is the english title of the manga. English string `json:"english" jsonschema:"description=English title of the manga."` // Native is the native title of the manga. (Usually in kanji) Native string `json:"native" jsonschema:"description=Native title of the manga. Usually in kanji."` } `json:"title"` AverageScore int `json:"averageScore" jsonschema:"description=Average score of the manga on Anilist."` // ID is the id of the manga on Anilist. ID int `json:"id" jsonschema:"description=ID of the manga on AnilistSearch."` // Description is the description of the manga in html format. Description string `json:"description" jsonschema:"description=Description of the manga in html format."` // CoverImage is the cover image of the manga. CoverImage struct { // ExtraLarge is the url of the extra large cover image. // If the image is not available, large will be used instead. ExtraLarge string `` /* 137-byte string literal not displayed */ // Large is the url of the large cover image. Large string `json:"large" jsonschema:"description=URL of the large cover image."` // Medium is the url of the medium cover image. Medium string `json:"medium" jsonschema:"description=URL of the medium cover image."` // Color is the average color of the cover image. Color string `json:"color" jsonschema:"description=Average color of the cover image."` } `json:"coverImage" jsonschema:"description=Cover image of the manga."` // BannerImage of the media BannerImage string `json:"bannerImage" jsonschema:"description=Banner image of the manga."` // Tags are the tags of the manga. Tags []struct { // Name of the tag. Name string `json:"name" jsonschema:"description=Name of the tag."` // Description of the tag. Description string `json:"description" jsonschema:"description=Description of the tag."` // Rank of the tag. How relevant it is to the manga from 1 to 100. Rank int `json:"rank" jsonschema:"description=Rank of the tag. How relevant it is to the manga from 1 to 100."` } `json:"tags"` // Genres of the manga Genres []string `json:"genres" jsonschema:"description=Genres of the manga."` // Characters are the primary characters of the manga. Characters struct { Nodes []struct { Name struct { // Full is the full name of the character. Full string `json:"full" jsonschema:"description=Full name of the character."` // Native is the native name of the character. Usually in kanji. Native string `json:"native" jsonschema:"description=Native name of the character. Usually in kanji."` } `json:"name"` } `json:"nodes"` } `json:"characters"` Staff struct { Edges []struct { Role string `json:"role" jsonschema:"description=Role of the staff member."` Node struct { Name struct { Full string `json:"full" jsonschema:"description=Full name of the staff member."` } `json:"name"` } `json:"node"` } `json:"edges"` } `json:"staff"` // StartDate is the date the manga started publishing. StartDate Date `json:"startDate" jsonschema:"description=Date the manga started publishing."` // EndDate is the date the manga ended publishing. EndDate Date `json:"endDate" jsonschema:"description=Date the manga ended publishing."` // Synonyms are the synonyms of the manga (Alternative titles). Synonyms []string `json:"synonyms" jsonschema:"description=Synonyms of the manga (Alternative titles)."` // Status is the status of the manga. (FINISHED, RELEASING, NOT_YET_RELEASED, CANCELLED) Status string `json:"status" jsonschema:"enum=FINISHED,enum=RELEASING,enum=NOT_YET_RELEASED,enum=CANCELLED,enum=HIATUS"` // IDMal is the id of the manga on MyAnimeList. IDMal int `json:"idMal" jsonschema:"description=ID of the manga on MyAnimeList."` // Chapters is the amount of chapters the manga has when complete. Chapters int `json:"chapters" jsonschema:"description=Amount of chapters the manga has when complete."` // SiteURL is the url of the manga on Anilist. SiteURL string `json:"siteUrl" jsonschema:"description=URL of the manga on AnilistSearch."` // Country of origin of the manga. Country string `json:"countryOfOrigin" jsonschema:"description=Country of origin of the manga."` // External urls related to the manga. External []struct { URL string `json:"url" jsonschema:"description=URL of the external link."` } `json:"externalLinks" jsonschema:"description=External links related to the manga."` }
func (AnilistManga) String ¶
func (a AnilistManga) String() string
type AnilistOptions ¶
type AnilistOptions struct { // HTTPClient is a http client used for Anilist API HTTPClient *http.Client // QueryToIDsStore maps query to ids. // single query to multiple ids. // // ["berserk" => [7, 42, 69], "death note" => [887, 3, 134]] QueryToIDsStore gokv.Store // TitleToIDStore maps title to id. // single title to single id. // // ["berserk" => 7, "death note" => 3] TitleToIDStore gokv.Store // IDToMangaStore maps id to manga. // single id to single manga. // // [7 => "{title: ..., image: ..., ...}"] IDToMangaStore gokv.Store AccessTokenStore gokv.Store // LogWriter used for logs progress Logger *Logger }
AnilistOptions is options for Anilist client
func DefaultAnilistOptions ¶
func DefaultAnilistOptions() AnilistOptions
DefaultAnilistOptions constructs default AnilistOptions
type Chapter ¶
type Chapter interface { fmt.Stringer Info() ChapterInfo // Volume gets the Volume that this Chapter is relevant to. // // Implementation should not make any external requests // nor be computationally heavy. Volume() Volume }
Chapter is what Volume consists of. Each chapter is about 24–40 pages.
type ChapterInfo ¶
type ChapterInfo struct { // Title is the title of chapter Title string `json:"title"` // URL is the url leading to chapter web page. URL string `json:"url"` // Number of the chapter. // // Float type used in case of chapters that has numbers // like this: 10.8 or 103.1. Number float32 `json:"number"` }
type ChapterOfMangaWithAnilist ¶
type ChapterOfMangaWithAnilist struct { Chapter MangaWithAnilist MangaWithAnilist }
func (ChapterOfMangaWithAnilist) ComicInfoXML ¶ added in v0.4.0
func (c ChapterOfMangaWithAnilist) ComicInfoXML() ComicInfoXML
type ChapterWithComicInfoXML ¶ added in v0.4.0
type ChapterWithComicInfoXML interface { Chapter // ComicInfoXML will be used to write ComicInfo.xml file. // If ok is false then mangal will try to search on Anilist for the // relevant manga. ComicInfoXML() (ComicInfoXML, error) }
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is the wrapper around Provider with the extended functionality. It's the core of the libmangal
func NewClient ¶
func NewClient( ctx context.Context, loader ProviderLoader, options ClientOptions, ) (*Client, error)
NewClient creates a new client from ProviderLoader. ClientOptions must be non-nil. Use DefaultClientOptions for defaults. It will validate ProviderLoader.Info and load the provider.
func (*Client) ChapterPages ¶
ChapterPages gets pages of the given chapter
func (*Client) ComputeChapterFilename ¶ added in v0.4.0
func (*Client) ComputeMangaFilename ¶ added in v0.4.0
func (*Client) ComputeVolumeFilename ¶ added in v0.4.0
func (*Client) DownloadChapter ¶
func (c *Client) DownloadChapter( ctx context.Context, chapter Chapter, options DownloadOptions, ) (string, error)
DownloadChapter downloads and saves chapter to the specified directory in the given format.
It will return resulting chapter path joined with DownloadOptions.Directory
func (*Client) DownloadPage ¶
DownloadPage downloads a page contents (image)
func (*Client) DownloadPagesInBatch ¶
func (c *Client) DownloadPagesInBatch( ctx context.Context, pages []Page, ) ([]PageWithImage, error)
DownloadPagesInBatch downloads multiple pages in batch by calling DownloadPage for each page in a separate goroutines. If any of the pages fails to download it will stop downloading other pages and return error immediately
func (*Client) MangaVolumes ¶
MangaVolumes gets chapters of the given manga
func (*Client) ReadChapter ¶ added in v0.8.0
func (*Client) SearchMangas ¶
SearchMangas searches for mangas with the given query
type ClientOptions ¶
type ClientOptions struct { // HTTPClient is http client that client would use for requests HTTPClient *http.Client // FS is a file system abstraction // that the client will use. FS afero.Fs // ChapterNameTemplate defines how mangas filenames will look when downloaded. MangaNameTemplate func( provider string, manga Manga, ) string // ChapterNameTemplate defines how volumes filenames will look when downloaded. // E.g. Vol. 1 VolumeNameTemplate func( provider string, volume Volume, ) string // ChapterNameTemplate defines how chapters filenames will look when downloaded. // E.g. "[001] chapter 1" or "Chainsaw Man - Ch. 1" ChapterNameTemplate func( provider string, chapter Chapter, ) string // Anilist is the Anilist client to use Anilist *Anilist }
ClientOptions is options that client would use during its runtime. See DefaultClientOptions
func DefaultClientOptions ¶
func DefaultClientOptions() ClientOptions
DefaultClientOptions constructs default ClientOptions
type ComicInfoXML ¶ added in v0.4.0
type ComicInfoXML struct { // Title of the book Title string // Series title of the series the book is part of. Series string // Number of the book in the series. Number float32 // Web a URL pointing to a reference website for the book. Web string // Genres of the book or series. For example, Science-Fiction or Shonen. Genres []string // Summary a description or summary of the book. Summary string // Count the total number of books in the series. Count int // Characters present in the book. Characters []string // Year of the book release Year int // Month of the book release Month int // Day of the book release Day int // Publisher person or organization responsible for // publishing, releasing, or issuing a resource. Publisher string // LanguageISO A language code describing the language of the book. LanguageISO string // StoryArc the story arc that books belong to. StoryArc string // StoryArcNumber While StoryArc was originally designed to store the arc within a series, // it was often used to indicate that a book was part of a reading order, composed of books // from multiple series. Mylar for instance was using the field as such. // // Since StoryArc itself wasn't able to carry the information about ordering of books // within a reading order, StoryArcNumber was added. // // StoryArc and StoryArcNumber can work in combination, to indicate in // which position the book is located at for a specific reading order. StoryArcNumber int // ScanInformation is a free text field, usually used to store information about who // scanned the book. ScanInformation string // AgeRating of the book. AgeRating string // CommunityRating Community rating of the book, from 0.0 to 5.0. CommunityRating float32 // Review of the book. Review string // GTIN a Global Trade Item Number identifying the book. // GTIN incorporates other standards like ISBN, ISSN, EAN, or JAN. // // https://en.wikipedia.org/wiki/Global_Trade_Item_Number GTIN string // Writers people or organizations responsible for creating the scenario. Writers []string // Format the original publication's binding format for scanned physical books or presentation format for digital sources. // // "TBP", "HC", "Web", "Digital" are common designators. Format string // Pencillers people or organizations responsible for drawing the art. Pencillers []string // Letterers people or organizations responsible for drawing text and speech bubbles. Letterers []string // Translators people or organizations responsible for rendering a text from one language into another, // or from an older form of a language into the modern form. // // This can also be used for fan translations ("scanlator"). Translators []string // Tags of the book or series. For example, ninja or school life. Tags []string // Notes a free text field, usually used to store information about // the application that created the ComicInfo.xml file. Notes string }
ComicInfoXML contains metadata information about a comic book. It is often used by comic book readers and management software to organize and display information about comic books in a library or collection.
type ComicInfoXMLOptions ¶ added in v0.4.0
type ComicInfoXMLOptions struct { // AddDate whether to add series release date or not AddDate bool // AlternativeDate use other date AlternativeDate *Date }
ComicInfoXMLOptions tweaks ComicInfoXML generation
func DefaultComicInfoOptions ¶
func DefaultComicInfoOptions() ComicInfoXMLOptions
DefaultComicInfoOptions constructs default ComicInfoXMLOptions
type DownloadOptions ¶
type DownloadOptions struct { // Format in which a chapter must be downloaded Format Format // Directory is the directory where manga will be downloaded to Directory string // CreateMangaDir will create manga directory CreateMangaDir bool // CreateVolumeDir will create volume directory. // // If CreateMangaDir is also true, volume directory // will be created under it. CreateVolumeDir bool // Strict means that that if during metadata creation // error occurs downloader will return it immediately and chapter // won't be downloaded Strict bool // SkipIfExists will skip downloading chapter if its already downloaded (exists at path) // // However, metadata will still be created if needed. SkipIfExists bool // DownloadMangaCover or not. Will not download cover again if its already downloaded. DownloadMangaCover bool // DownloadMangaBanner or not. Will not download banner again if its already downloaded. DownloadMangaBanner bool // WriteSeriesJson write metadata series.json file in the manga directory WriteSeriesJson bool // WriteComicInfoXml write metadata ComicInfo.xml file to the .cbz archive when // downloading with FormatCBZ WriteComicInfoXml bool // ReadAfter will open the chapter for reading after it was downloaded. // It will use os default app for resulting mimetype. // // E.g. `xdg-open` for Linux. // // It will also sync read chapter with your Anilist profile // if it's configured. See also ReadIncognito // // Note, that underlying filesystem must be mapped with OsFs // in order for os to open it. ReadAfter bool ReadOptions ReadOptions // ComicInfoXMLOptions options to use for ComicInfo.xml when WriteComicInfoXml is true ComicInfoXMLOptions ComicInfoXMLOptions // ImageTransformer is applied for each image for the chapter. // // E.g. grayscale effect ImageTransformer func([]byte) ([]byte, error) }
DownloadOptions configures Chapter downloading
func DefaultDownloadOptions ¶
func DefaultDownloadOptions() DownloadOptions
DefaultDownloadOptions constructs default DownloadOptions
type Format ¶
type Format uint8
Format is the format for saving chapters
const ( // FormatPDF saves chapter as a PDF document FormatPDF Format = iota + 1 // FormatImages saves chapter as a directory of plain images FormatImages // FormatCBZ saves chapter as CBZ archive. // CBZ stands for Comic Book Zip format. // Common among comic readers FormatCBZ // FormatTAR saves chapter images as tar archive FormatTAR // FormatTARGZ saves chapter images tar.gz archive FormatTARGZ // FormatZIP save chapter images as zip archive FormatZIP )
func FormatString ¶
FormatString retrieves an enum value from the enum constants string name. Throws an error if the param is not part of the enum.
func (Format) Extension ¶ added in v0.4.0
Extension returns extension of the format with the leading dot.
func (Format) IsAFormat ¶
IsAFormat returns "true" if the value is listed in the enum definition. "false" otherwise
func (Format) MarshalJSON ¶ added in v0.4.0
MarshalJSON implements the json.Marshaler interface for Format
func (Format) MarshalText ¶ added in v0.4.0
MarshalText implements the encoding.TextMarshaler interface for Format
func (Format) MarshalYAML ¶ added in v0.4.0
MarshalYAML implements a YAML Marshaler for Format
func (*Format) UnmarshalJSON ¶ added in v0.4.0
UnmarshalJSON implements the json.Unmarshaler interface for Format
func (*Format) UnmarshalText ¶ added in v0.4.0
UnmarshalText implements the encoding.TextUnmarshaler interface for Format
func (*Format) UnmarshalYAML ¶ added in v0.4.0
UnmarshalYAML implements a YAML Unmarshaler for Format
type HistoryEntry ¶ added in v0.8.0
type MangaInfo ¶
type MangaInfo struct { // Title of the manga Title string `json:"title"` // AnilistSearch is the title of the manga // that will be used for on Anilist. // // This is a separate field from the Title due to Title could // be on any language, but Anilist only supports searching // for english, native and romaji titles. AnilistSearch string `json:"anilistSearch"` // URL leading to manga page web page. URL string `json:"url"` // ID of the Manga. It must be unique withing its provider. ID string `json:"id"` // Cover is the cover image url. Cover string `json:"cover"` // Banner is the banner image url. Banner string `json:"banner"` }
type MangaWithAnilist ¶
type MangaWithAnilist struct { Manga Anilist AnilistManga }
func (*MangaWithAnilist) SeriesJSON ¶ added in v0.4.0
func (m *MangaWithAnilist) SeriesJSON() SeriesJSON
type MangaWithSeriesJSON ¶ added in v0.4.0
type MangaWithSeriesJSON interface { Manga // SeriesJSON will be used to write series.json file. // If ok is false then mangal will try to search on Anilist for the // relevant manga. SeriesJSON() (SeriesJSON, error) }
type MetadataError ¶ added in v0.3.0
type MetadataError struct {
// contains filtered or unexported fields
}
type Page ¶
type Page interface { fmt.Stringer // GetExtension gets the image extension of this page. // An extension must start with the dot. // // For example: .jpeg .png GetExtension() string // Chapter gets the Chapter that this Page is relevant to. // // Implementation should not make any external requests // nor be computationally heavy. Chapter() Chapter }
Page is what Chapter consists of.
type PageWithImage ¶
type PageWithImage interface { Page // GetImage gets the image contents. This operation should not perform any extra requests. // Implementation should expose this method only if the Page already contains image contents. GetImage() []byte // SetImage sets the image contents. This is used by DownloadOptions.ImageTransformer SetImage(newImage []byte) }
PageWithImage is a Page with downloaded image
type Provider ¶
type Provider interface { fmt.Stringer io.Closer // Info information about Provider Info() ProviderInfo // SetLogger sets logger to use for this provider SetLogger(*Logger) // SearchMangas searches for mangas with the given query. // // Implementation should utilize given logger SearchMangas( ctx context.Context, query string, ) ([]Manga, error) // MangaVolumes gets volumes of the manga // // Implementation should utilize given logger MangaVolumes( ctx context.Context, manga Manga, ) ([]Volume, error) // VolumeChapters gets chapters of the given volume. // // Implementation should utilize given logger VolumeChapters( ctx context.Context, volume Volume, ) ([]Chapter, error) // ChapterPages gets pages of the given chapter. // // Implementation should utilize given logger ChapterPages( ctx context.Context, chapter Chapter, ) ([]Page, error) // GetPageImage gets raw image contents of the given page. // // Implementation should utilize given loggger GetPageImage( ctx context.Context, page Page, ) ([]byte, error) }
Provider exposes methods for searching mangas, getting chapters, pages and images
type ProviderInfo ¶
type ProviderInfo struct { // ID is the unique identifier of the provider ID string `json:"id"` // Name is the non-empty name of the provider Name string `json:"name"` // Version is a semantic version of the provider. // // "v" prefix is not permitted. // E.g. "0.1.0" is valid, but "v0.1.0" is not. // // See https://semver.org/ Version string `json:"version"` // Description of the provider. May be empty. Description string `json:"description"` // Website of the provider. May be empty. Website string `json:"website"` }
ProviderInfo is the passport of the provider
func (ProviderInfo) Validate ¶
func (p ProviderInfo) Validate() error
Validate checks if the ProviderInfo is valid. This means that ProviderInfo.Name is non-empty and ProviderInfo.Version is a valid semver
type ProviderLoader ¶
type ProviderLoader interface { fmt.Stringer // Info information about Provider Info() ProviderInfo // Load loads the Provider Load(ctx context.Context) (Provider, error) }
ProviderLoader gives information about provider without loading it first.
type ReadOptions ¶ added in v0.8.0
type ReadOptions struct { // SaveHistory will save chapter to local history if ReadAfter is enabled. SaveHistory bool // ReadIncognito will save Anilist reading history if ReadAfter is enabled and logged in to the Anilist. SaveAnilist bool }
func DefaultReadOptions ¶ added in v0.8.0
func DefaultReadOptions() ReadOptions
type SeriesJSON ¶ added in v0.4.0
type SeriesJSON struct { Type string `json:"type"` Name string `json:"name"` DescriptionFormatted string `json:"descriptionFormatted"` DescriptionText string `json:"descriptionText"` Status string `json:"status"` Year int `json:"year"` ComicImage string `json:"ComicImage"` Publisher string `json:"publisher"` ComicID int `json:"comicId"` BookType string `json:"booktype"` TotalIssues int `json:"totalIssues"` PublicationRun string `json:"publication_run"` }
SeriesJSON is similar to ComicInfoXML but designed for the series as a whole rather than a single chapter
type Volume ¶
type Volume interface { fmt.Stringer Info() VolumeInfo // Manga gets the Manga that this Volume is relevant to. // // Implementation should not make any external requests // nor be computationally heavy. Manga() Manga }
Volume if a series is popular enough, its chapters are then collected and published into volumes, which usually feature a few chapters of the overall story. Most Manga series are long-running and can span multiple volumes.
Mangal expects that each Manga must have at least one Volume
type VolumeInfo ¶
type VolumeInfo struct { // Number of the volume. Must be greater than 0 Number int `json:"number"` }