libmangal

package module
v0.20.1 Latest Latest
Warning

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

Go to latest
Published: Jul 31, 2024 License: Unlicense Imports: 24 Imported by: 31

README

logo depicting a cartoon octopus

libmangal

Go Reference

Warning

The API is not stable and may change at any time.

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

Designed to be the backend for applications such as CLI, TUI, web apps, gRPC server, etc.

Note: This is a fork of mangalorg/libmangal.

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/luevano/libmangal@latest

Providers

Apps using libmangal

  • mangal - Advanced CLI manga downloader. Lua scrapers, export formats, anilist integration, fancy TUI and more.
  • mangalcli - Advanced Manga Downloader with Anilist integration, metadata generation and Lua extensions.

Credits

Octopus logo: Octopus icons created by Freepik - Flaticon

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FormatStrings

func FormatStrings() []string

FormatStrings returns a slice of all String values of the enum

Types

type Client

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

Client is a wrapper around Provider with extended functionality.

It's the core of libmangal.

func NewClient

func NewClient(
	ctx context.Context,
	loader ProviderLoader,
	options ClientOptions,
) (*Client, error)

NewClient creates a new client from given ProviderLoader.

ClientOptions must be non-zero. Use DefaultClientOptions for defaults. It will validate ProviderLoader.Info and load the provider.

func (*Client) ChapterName added in v0.17.2

func (c *Client) ChapterName(chapter mangadata.Chapter, format Format) string

ChapterName determines the chapter file name. E.g. "[001] chapter 1" or "Chainsaw Man - Ch. 1"

func (*Client) ChapterPages

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

ChapterPages gets pages of the given chapter.

func (*Client) Close

func (c *Client) Close() error

func (*Client) DownloadChapter

func (c *Client) DownloadChapter(
	ctx context.Context,
	chapter mangadata.Chapter,
	options DownloadOptions,
) (*metadata.DownloadedChapter, error)

DownloadChapter downloads and writes chapter to disk with the given DownloadOptions.

It will return resulting chapter download information via metadata.DownloadedChapter.

func (*Client) DownloadPage

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

DownloadPage downloads a page contents (image).

func (*Client) DownloadPagesInBatch

func (c *Client) DownloadPagesInBatch(
	ctx context.Context,
	pages []mangadata.Page,
) ([]mangadata.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

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

FS returns the client's FileSystem.

func (*Client) GetMetadataProvider added in v0.20.0

func (c *Client) GetMetadataProvider(id metadata.IDSource) (*metadata.ProviderWithCache, error)

GetMetadataProvider returns the requested metadata Provider for the given id.

func (*Client) Info

func (c *Client) Info() ProviderInfo

Info returns info about provider.

func (*Client) Logger

func (c *Client) Logger() *logger.Logger

Logger returns the client's Logger.

func (*Client) MangaName added in v0.17.2

func (c *Client) MangaName(manga mangadata.Manga) string

MangaName determines the manga directory name.

func (*Client) MangaVolumes

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

MangaVolumes gets chapters of the given manga.

func (*Client) ProviderName added in v0.17.2

func (c *Client) ProviderName(provider ProviderInfo) string

ProviderName determines the provider directory name.

func (*Client) ReadChapter

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

ReadChapter opens the chapter for reading and marks it as read if authorized. 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.

Note, that underlying filesystem must be mapped with OsFs in order for os to open it.

func (*Client) SearchByManga added in v0.20.0

func (c *Client) SearchByManga(
	ctx context.Context,
	provider *metadata.ProviderWithCache,
	manga mangadata.Manga,
) (metadata.Metadata, bool, error)

SearchByManga is a convenience method to search given a Manga. It's meant to be used by the SearchMetadata method.

Tries to search manga metadata in the following order:

1. If the manga contains non-nil metadata, by its metadata ID if available.

2. If the manga title is binded to a metadata ID.

3. Find closest manga metadata (FindClosest) by using the manga Title field.

func (*Client) SearchMangas

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

SearchMangas searches for mangas with the given query.

func (*Client) SearchMetadata added in v0.16.0

func (c *Client) SearchMetadata(
	ctx context.Context,
	manga mangadata.Manga,
) (metadata.Metadata, error)

SearchMetadata will search for metadata on the available metadata providers.

Tries to search manga metadata in the following order:

1. If the manga contains non-nil metadata, by its metadata ID if available.

2. If the manga Title field is binded to a metadata ID.

3. Find closest manga metadata (FindClosest) by using the manga Title field.

func (*Client) SetMetadataProvider added in v0.20.1

func (c *Client) SetMetadataProvider(provider *metadata.ProviderWithCache) error

SetMetadataProvider will add or update the given metadata Provider.

func (*Client) String

func (c *Client) String() string

func (*Client) VolumeChapters

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

VolumeChapters gets chapters of the given manga.

func (*Client) VolumeName added in v0.17.2

func (c *Client) VolumeName(volume mangadata.Volume) string

VolumeName determines the volume directory name. E.g. "Vol. 1" or "Volume 1"

type ClientOptions

type ClientOptions struct {
	// TODO: move HTTPClient (and UserAgent) out of the options?
	//
	// HTTPClient is http client that client would use for requests.
	HTTPClient *http.Client

	// UserAgent to use when making HTTP requests.
	UserAgent string

	// FS is a file system abstraction that the client will use.
	FS afero.Fs

	// ModeDir is the permission bits used for all dirs created.
	ModeDir fs.FileMode

	// ModeFile is the permission bits used for all files created.
	ModeFile fs.FileMode

	// ProviderName determines the provider directory name.
	ProviderName func(
		provider ProviderInfo,
	) string

	// MangaName determines the manga directory name.
	MangaName func(
		provider ProviderInfo,
		manga mangadata.Manga,
	) string

	// VolumeName determines the volume directory name.
	// E.g. "Vol. 1" or "Volume 1"
	VolumeName func(
		provider ProviderInfo,
		volume mangadata.Volume,
	) string

	// ChapterName determines the chapter file name.
	// E.g. "[001] chapter 1" or "Chainsaw Man - Ch. 1"
	ChapterName func(
		provider ProviderInfo,
		chapter mangadata.Chapter,
	) string
}

ClientOptions is options that client would use during its runtime.

func DefaultClientOptions

func DefaultClientOptions() ClientOptions

DefaultClientOptions constructs default ClientOptions, with default Anilist options as well.

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

	// CreateProviderDir will create provider directory.
	CreateProviderDir bool

	// 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 the metadata is invalid or if an error occurs during
	// metadata files creation, the chapter will not be written to disk.
	//
	// Some metadata is potentially written to disk.
	Strict bool

	// SkipIfExists will skip downloading chapter if its already downloaded (exists at path).
	//
	// However, metadata will still be created if needed.
	SkipIfExists bool

	// SearchMetadata will search for metadata on the available metadata providers,
	// and use the found metadata regardless of the incoming manga metadata which
	// could result in `nil` metadata when not found.
	//
	// Search priority is always by ID (if provided as part of one of the metadata fields), then by the title.
	SearchMetadata 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

	// SkipSeriesJSONIfOngoing will avoid writing series.json file for ongoing series,
	// due to lack of TotalIssues metadata provided by Anilist for example.
	//
	// There are issues with _some_ parsers when the TotalIssues is zero (I see you, Komga),
	// so this is a workaround. Also this avoids checks to overwrite series.json on each chapter,
	// silly, no (if only Komga would fix that)?
	SkipSeriesJSONIfOngoing bool

	// WriteComicInfoXML write metadata ComicInfo.xml file to the .cbz archive when
	// downloading with FormatCBZ.
	WriteComicInfoXML bool

	// ComicInfoXMLOptions options to use for ComicInfo.xml when WriteComicInfoXml is true.
	ComicInfoXMLOptions metadata.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

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

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

MarshalJSON implements the json.Marshaler interface for Format

func (Format) MarshalText

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

MarshalText implements the encoding.TextMarshaler interface for Format

func (Format) MarshalYAML

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

MarshalYAML implements a YAML Marshaler for Format

func (Format) String

func (i Format) String() string

func (*Format) UnmarshalJSON

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

UnmarshalJSON implements the json.Unmarshaler interface for Format

func (*Format) UnmarshalText

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

UnmarshalText implements the encoding.TextUnmarshaler interface for Format

func (*Format) UnmarshalYAML

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

UnmarshalYAML implements a YAML Unmarshaler for Format

type HistoryEntry

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

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.Logger)

	// SearchMangas searches for mangas with the given query.
	//
	// Implementation should utilize given logger.
	SearchMangas(
		ctx context.Context,
		query string,
	) ([]mangadata.Manga, error)

	// MangaVolumes gets volumes of the manga.
	//
	// Implementation should utilize given logger.
	MangaVolumes(
		ctx context.Context,
		manga mangadata.Manga,
	) ([]mangadata.Volume, error)

	// VolumeChapters gets chapters of the given volume.
	//
	// Implementation should utilize given logger.
	VolumeChapters(
		ctx context.Context,
		volume mangadata.Volume,
	) ([]mangadata.Chapter, error)

	// ChapterPages gets pages of the given chapter.
	//
	// Implementation should utilize given logger
	ChapterPages(
		ctx context.Context,
		chapter mangadata.Chapter,
	) ([]mangadata.Page, error)

	// GetPageImage gets raw image contents of the given page.
	//
	// Implementation should utilize given logger.
	GetPageImage(
		ctx context.Context,
		page mangadata.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

type ReadOptions struct {
	// SaveHistory will save chapter to local history if ReadAfter is enabled.
	SaveHistory bool

	// SaveAnilist will save Anilist reading history if logged in and ReadAfter is enabled.
	SaveAnilist bool

	// SaveMyAnimeList will save MyAnimeList reading history if logged in and ReadAfter is enabled.
	SaveMyAnimeList bool
}

ReadOptions configures the reader options.

func DefaultReadOptions

func DefaultReadOptions() ReadOptions

DefaultReadOptions constructs default ReadOptions.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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