libmangal

package module
v0.8.0 Latest Latest
Warning

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

Go to latest
Published: Aug 16, 2023 License: Unlicense Imports: 25 Imported by: 3

README

logo depicting a cartoon octopus

libmangal β

Warning

This is a beta software. The API is not stable and may change at any time.

This is the engine for downloading, managing, tagging, reading manga with native Anilist integration. A powerful wrapper around anything that implements its Provider interface.

It's designed to be a backend for various frontends that can be built on top of it. Such as a CLI, a web app, a mobile app, gRPC server, etc. Anything!

Features

  • Smart caching - only download what you need
  • Different export formats
    • PDF - chapters stored a single PDF file
    • CBZ - Comic Book ZIP format
    • TAR - TAR archive
    • ZIP - ZIP archive
    • Images - a plain directory of images
  • Monolith - no runtime dependencies.
  • Generates metadata files
    • ComicInfo.xml - The ComicInfo.xml file originates from the ComicRack application, which is not developed anymore. The ComicInfo.xml however is used by a variety of applications.
    • series.json - A JSON file containing metadata about the series. Originates from mylar3
  • Automatically populates missing metadata by querying Anilist.
  • Filesystem abstraction - can be used with any filesystem that implements afero
    • Remote filesystems
    • In-memory filesystems
    • etc.
  • Highly configurable
    • Define how you want to name your files
    • Define how you want to organize your files
    • Define how you want to tag your files
    • Define how you want to cache your files
  • Cross-platform - every OS that Go compiles to is supported
    • Windows
    • Linux
    • MacOS
    • WASM
    • etc.

Install

go get github.com/mangalorg/libmangal@latest

Providers

Apps using libmangal

  • mangalcli - Advanced Manga Downloader with Anilist integration, metadata generation and Lua extensions.

Documentation

Index

Constants

View Source
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 (a *Anilist) BindTitleWithID(title string, anilistMangaId int) error

func (*Anilist) FindClosestManga

func (a *Anilist) FindClosestManga(
	ctx context.Context,
	title string,
) (AnilistManga, bool, error)

func (*Anilist) GetByID

func (a *Anilist) GetByID(
	ctx context.Context,
	id int,
) (AnilistManga, bool, error)

GetByID gets anilist manga by its id

func (*Anilist) IsAuthorized

func (a *Anilist) IsAuthorized() bool

func (*Anilist) Logout added in v0.8.0

func (a *Anilist) Logout() error

func (*Anilist) MakeChapterWithAnilist

func (a *Anilist) MakeChapterWithAnilist(
	ctx context.Context,
	chapter Chapter,
) (ChapterOfMangaWithAnilist, bool, error)

func (*Anilist) MakeMangaWithAnilist

func (a *Anilist) MakeMangaWithAnilist(
	ctx context.Context,
	manga Manga,
) (MangaWithAnilist, bool, error)

func (*Anilist) SearchMangas

func (a *Anilist) SearchMangas(
	ctx context.Context,
	query string,
) ([]AnilistManga, error)

func (*Anilist) SetMangaProgress added in v0.6.1

func (a *Anilist) SetMangaProgress(ctx context.Context, mangaID, chapterNumber int) error

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 AnilistLoginCredentials struct {
	ID     string
	Secret string
	Code   string
}

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) Anilist added in v0.4.0

func (c *Client) Anilist() *Anilist

func (*Client) ChapterPages

func (c *Client) ChapterPages(ctx context.Context, chapter Chapter) ([]Page, error)

ChapterPages gets pages of the given chapter

func (*Client) Close added in v0.8.0

func (c *Client) Close() error

func (*Client) ComputeChapterFilename added in v0.4.0

func (c *Client) ComputeChapterFilename(chapter Chapter, format Format) string

func (*Client) ComputeMangaFilename added in v0.4.0

func (c *Client) ComputeMangaFilename(manga Manga) string

func (*Client) ComputeVolumeFilename added in v0.4.0

func (c *Client) ComputeVolumeFilename(volume Volume) string

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

func (c *Client) DownloadPage(ctx context.Context, page Page) (PageWithImage, error)

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) FS added in v0.4.0

func (c *Client) FS() afero.Fs

func (*Client) Info

func (c *Client) Info() ProviderInfo

Info returns info about provider

func (*Client) Logger added in v0.8.0

func (c *Client) Logger() *Logger

func (*Client) MangaVolumes

func (c *Client) MangaVolumes(ctx context.Context, manga Manga) ([]Volume, error)

MangaVolumes gets chapters of the given manga

func (*Client) ReadChapter added in v0.8.0

func (c *Client) ReadChapter(ctx context.Context, path string, chapter Chapter, options ReadOptions) error

func (*Client) SearchMangas

func (c *Client) SearchMangas(ctx context.Context, query string) ([]Manga, error)

SearchMangas searches for mangas with the given query

func (*Client) String

func (c *Client) String() string

func (*Client) VolumeChapters

func (c *Client) VolumeChapters(ctx context.Context, volume Volume) ([]Chapter, error)

VolumeChapters gets chapters of the given manga

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 Date

type Date struct {
	Year  int `json:"year"`
	Month int `json:"month"`
	Day   int `json:"day"`
}

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

func FormatString(s string) (Format, error)

FormatString retrieves an enum value from the enum constants string name. Throws an error if the param is not part of the enum.

func FormatValues

func FormatValues() []Format

FormatValues returns all values of the enum

func (Format) Extension added in v0.4.0

func (f Format) Extension() string

Extension returns extension of the format with the leading dot.

func (Format) IsAFormat

func (i Format) IsAFormat() bool

IsAFormat returns "true" if the value is listed in the enum definition. "false" otherwise

func (Format) MarshalJSON added in v0.4.0

func (i Format) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaler interface for Format

func (Format) MarshalText added in v0.4.0

func (i Format) MarshalText() ([]byte, error)

MarshalText implements the encoding.TextMarshaler interface for Format

func (Format) MarshalYAML added in v0.4.0

func (i Format) MarshalYAML() (interface{}, error)

MarshalYAML implements a YAML Marshaler for Format

func (Format) String

func (i Format) String() string

func (*Format) UnmarshalJSON added in v0.4.0

func (i *Format) UnmarshalJSON(data []byte) error

UnmarshalJSON implements the json.Unmarshaler interface for Format

func (*Format) UnmarshalText added in v0.4.0

func (i *Format) UnmarshalText(text []byte) error

UnmarshalText implements the encoding.TextUnmarshaler interface for Format

func (*Format) UnmarshalYAML added in v0.4.0

func (i *Format) UnmarshalYAML(unmarshal func(interface{}) error) error

UnmarshalYAML implements a YAML Unmarshaler for Format

type HistoryEntry added in v0.8.0

type HistoryEntry struct {
	ProviderID    string
	MangaID       string
	VolumeNumber  int
	ChapterNumber float64
}

type Logger added in v0.8.0

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

func NewLogger added in v0.8.0

func NewLogger() *Logger

func (*Logger) Log added in v0.8.0

func (l *Logger) Log(message string)

func (*Logger) SetOnLog added in v0.8.0

func (l *Logger) SetOnLog(hook func(string))

func (*Logger) SetOutput added in v0.8.0

func (l *Logger) SetOutput(writer io.Writer)

func (*Logger) SetPrefix added in v0.8.0

func (l *Logger) SetPrefix(prefix string)

func (*Logger) Writer added in v0.8.0

func (l *Logger) Writer() io.Writer

type Manga

type Manga interface {
	fmt.Stringer

	Info() MangaInfo
}

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"`
}

Jump to

Keyboard shortcuts

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