models

package
v0.0.20 Latest Latest
Warning

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

Go to latest
Published: Mar 15, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Index

Constants

View Source
const (
	//tygo:emit export type DataSource = typeof DataSourceManual | typeof DataSourceSidecar | typeof DataSourcePlugin | typeof DataSourceFileMetadata | typeof DataSourceExistingCover | typeof DataSourceEPUBMetadata | typeof DataSourceCBZMetadata | typeof DataSourceM4BMetadata | typeof DataSourcePDFMetadata | typeof DataSourceFilepath | `plugin:${string}`;
	DataSourceManual        = "manual"
	DataSourceSidecar       = "sidecar"
	DataSourcePlugin        = "plugin"
	DataSourceFileMetadata  = "file_metadata"
	DataSourceExistingCover = "existing_cover"
	DataSourceEPUBMetadata  = "epub_metadata"
	DataSourceCBZMetadata   = "cbz_metadata"
	DataSourceM4BMetadata   = "m4b_metadata"
	DataSourcePDFMetadata   = "pdf_metadata"
	DataSourceFilepath      = "filepath"

	// DataSourcePluginPrefix is the prefix for plugin-specific data sources.
	// Actual values are "plugin:scope/id" (e.g., "plugin:shisho/goodreads-metadata").
	DataSourcePluginPrefix = "plugin:"
)
View Source
const (
	DataSourceManualPriority       = 0
	DataSourceSidecarPriority      = 1 // Sidecar has higher priority than file metadata
	DataSourcePluginPriority       = 2 // Plugin enricher/parser results
	DataSourceFileMetadataPriority = 3 // All file-derived sources share this
	DataSourceFilepathPriority     = 4
)

Lower priority means that we respect it more than higher priority.

View Source
const (
	//tygo:emit export type IdentifierType = typeof IdentifierTypeISBN10 | typeof IdentifierTypeISBN13 | typeof IdentifierTypeASIN | typeof IdentifierTypeUUID | typeof IdentifierTypeGoodreads | typeof IdentifierTypeGoogle | typeof IdentifierTypeOther | (string & {});
	IdentifierTypeISBN10    = "isbn_10"
	IdentifierTypeISBN13    = "isbn_13"
	IdentifierTypeASIN      = "asin"
	IdentifierTypeUUID      = "uuid"
	IdentifierTypeGoodreads = "goodreads"
	IdentifierTypeGoogle    = "google"
	IdentifierTypeOther     = "other"
)

FileIdentifier type constants.

View Source
const (
	//tygo:emit export type FileType = typeof FileTypeCBZ | typeof FileTypeEPUB | typeof FileTypeM4B | typeof FileTypePDF;
	FileTypeCBZ  = "cbz"
	FileTypeEPUB = "epub"
	FileTypeM4B  = "m4b"
	FileTypePDF  = "pdf"
)
View Source
const (
	//tygo:emit export type FileRole = typeof FileRoleMain | typeof FileRoleSupplement;
	FileRoleMain       = "main"
	FileRoleSupplement = "supplement"
)
View Source
const (
	//tygo:emit export type JobStatus = typeof JobStatusPending | typeof JobStatusInProgress | typeof JobStatusCompleted | typeof JobStatusFailed;
	JobStatusPending    = "pending"
	JobStatusInProgress = "in_progress"
	JobStatusCompleted  = "completed"
	JobStatusFailed     = "failed"
)
View Source
const (
	//tygo:emit export type JobType = typeof JobTypeExport | typeof JobTypeScan;
	JobTypeExport = "export"
	JobTypeScan   = "scan"
)
View Source
const (
	//tygo:emit export type JobLogLevel = typeof JobLogLevelInfo | typeof JobLogLevelWarn | typeof JobLogLevelError | typeof JobLogLevelFatal;
	JobLogLevelInfo  = "info"
	JobLogLevelWarn  = "warn"
	JobLogLevelError = "error"
	JobLogLevelFatal = "fatal"
)
View Source
const (
	DownloadFormatOriginal = "original"
	DownloadFormatKepub    = "kepub"
	DownloadFormatAsk      = "ask"
)

Download format preference constants.

View Source
const (
	ListPermissionViewer  = "viewer"
	ListPermissionEditor  = "editor"
	ListPermissionManager = "manager"
)

List permission levels.

View Source
const (
	ListSortAddedAtDesc = "added_at_desc"
	ListSortAddedAtAsc  = "added_at_asc"
	ListSortTitleAsc    = "title_asc"
	ListSortTitleDesc   = "title_desc"
	ListSortAuthorAsc   = "author_asc"
	ListSortAuthorDesc  = "author_desc"
	ListSortManual      = "manual"
)

List default sort options.

View Source
const (
	AuthorRoleWriter      = "writer"
	AuthorRolePenciller   = "penciller"
	AuthorRoleInker       = "inker"
	AuthorRoleColorist    = "colorist"
	AuthorRoleLetterer    = "letterer"
	AuthorRoleCoverArtist = "cover_artist"
	AuthorRoleEditor      = "editor"
	AuthorRoleTranslator  = "translator"
)

Author role constants for CBZ ComicInfo.xml creator types.

View Source
const (
	//tygo:emit export type PluginHookType = typeof PluginHookInputConverter | typeof PluginHookFileParser | typeof PluginHookOutputGenerator | typeof PluginHookMetadataEnricher;
	PluginHookInputConverter   = "inputConverter"
	PluginHookFileParser       = "fileParser"
	PluginHookOutputGenerator  = "outputGenerator"
	PluginHookMetadataEnricher = "metadataEnricher"
)

Plugin hook type constants.

View Source
const (
	ResourceLibraries = "libraries"
	ResourceBooks     = "books"
	ResourcePeople    = "people"
	ResourceSeries    = "series"
	ResourceUsers     = "users"
	ResourceJobs      = "jobs"
	ResourceConfig    = "config"
)

Permission resources.

View Source
const (
	OperationRead  = "read"
	OperationWrite = "write"
)

Permission operations.

View Source
const (
	RoleAdmin  = "admin"
	RoleEditor = "editor"
	RoleViewer = "viewer"
)

Predefined role names.

View Source
const (
	//tygo:emit export type FitMode = typeof FitModeHeight | typeof FitModeOriginal;
	FitModeHeight   = "fit-height"
	FitModeOriginal = "original"
)

Variables

This section is empty.

Functions

func GetDataSourcePriority

func GetDataSourcePriority(source string) int

GetDataSourcePriority returns the priority for a given data source string. Handles "plugin:scope/id" format by matching the prefix.

func PluginDataSource

func PluginDataSource(scope, id string) string

PluginDataSource returns a data source string for a specific plugin (e.g., "plugin:shisho/goodreads").

Types

type Author

type Author struct {
	bun.BaseModel `bun:"table:authors,alias:a" tstype:"-"`

	ID        int     `bun:",pk,nullzero" json:"id"`
	BookID    int     `bun:",nullzero" json:"book_id"`
	PersonID  int     `bun:",nullzero" json:"person_id"`
	Person    *Person `bun:"rel:belongs-to,join:person_id=id" json:"person,omitempty" tstype:"Person"`
	SortOrder int     `bun:",nullzero" json:"sort_order"`
	Role      *string `json:"role"` // CBZ creator role: writer, penciller, inker, etc. NULL for generic author
}

type Book

type Book struct {
	bun.BaseModel `bun:"table:books,alias:b" tstype:"-"`

	ID                int           `bun:",pk,nullzero" json:"id"`
	CreatedAt         time.Time     `json:"created_at"`
	UpdatedAt         time.Time     `json:"updated_at"`
	LibraryID         int           `bun:",nullzero" json:"library_id"`
	Library           *Library      `bun:"rel:belongs-to" json:"library" tstype:"Library"`
	Filepath          string        `bun:",nullzero" json:"filepath"`
	Title             string        `bun:",nullzero" json:"title"`
	TitleSource       string        `bun:",nullzero" json:"title_source" tstype:"DataSource"`
	SortTitle         string        `bun:",notnull" json:"sort_title"`
	SortTitleSource   string        `bun:",notnull" json:"sort_title_source" tstype:"DataSource"`
	Subtitle          *string       `json:"subtitle"`
	SubtitleSource    *string       `json:"subtitle_source" tstype:"DataSource"`
	Description       *string       `json:"description"`
	DescriptionSource *string       `json:"description_source" tstype:"DataSource"`
	Authors           []*Author     `bun:"rel:has-many,join:id=book_id" json:"authors,omitempty" tstype:"Author[]"`
	AuthorSource      string        `bun:",nullzero" json:"author_source" tstype:"DataSource"`
	BookSeries        []*BookSeries `bun:"rel:has-many,join:id=book_id" json:"book_series,omitempty" tstype:"BookSeries[]"`
	BookGenres        []*BookGenre  `bun:"rel:has-many,join:id=book_id" json:"book_genres,omitempty" tstype:"BookGenre[]"`
	GenreSource       *string       `json:"genre_source" tstype:"DataSource"`
	BookTags          []*BookTag    `bun:"rel:has-many,join:id=book_id" json:"book_tags,omitempty" tstype:"BookTag[]"`
	TagSource         *string       `json:"tag_source" tstype:"DataSource"`
	PrimaryFileID     *int          `json:"primary_file_id"`
	Files             []*File       `bun:"rel:has-many" json:"files" tstype:"File[]"`
}

type BookGenre

type BookGenre struct {
	bun.BaseModel `bun:"table:book_genres,alias:bg" tstype:"-"`

	ID      int    `bun:",pk,nullzero" json:"id"`
	BookID  int    `bun:",nullzero" json:"book_id"`
	GenreID int    `bun:",nullzero" json:"genre_id"`
	Genre   *Genre `bun:"rel:belongs-to,join:genre_id=id" json:"genre,omitempty" tstype:"Genre"`
}

type BookIdentifier

type BookIdentifier struct {
	bun.BaseModel `bun:"table:book_identifiers,alias:bi" tstype:"-"`

	ID        int       `bun:",pk,nullzero" json:"id"`
	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
	BookID    int       `bun:",nullzero" json:"book_id"`
	Type      string    `bun:",nullzero" json:"type"` // TODO: make enum
	Value     string    `bun:",nullzero" json:"value"`
}

type BookSeries

type BookSeries struct {
	bun.BaseModel `bun:"table:book_series,alias:bs" tstype:"-"`

	ID           int      `bun:",pk,nullzero" json:"id"`
	BookID       int      `bun:",nullzero" json:"book_id"`
	SeriesID     int      `bun:",nullzero" json:"series_id"`
	Series       *Series  `bun:"rel:belongs-to,join:series_id=id" json:"series,omitempty" tstype:"Series"`
	SeriesNumber *float64 `json:"series_number,omitempty"`
	SortOrder    int      `bun:",nullzero" json:"sort_order"`
}

type BookTag

type BookTag struct {
	bun.BaseModel `bun:"table:book_tags,alias:bt" tstype:"-"`

	ID     int  `bun:",pk,nullzero" json:"id"`
	BookID int  `bun:",nullzero" json:"book_id"`
	TagID  int  `bun:",nullzero" json:"tag_id"`
	Tag    *Tag `bun:"rel:belongs-to,join:tag_id=id" json:"tag,omitempty" tstype:"Tag"`
}

type Chapter

type Chapter struct {
	bun.BaseModel `bun:"table:chapters,alias:ch" tstype:"-"`

	ID        int       `bun:",pk,autoincrement" json:"id"`
	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
	FileID    int       `bun:",notnull" json:"file_id"`
	ParentID  *int      `json:"parent_id"`
	SortOrder int       `bun:",notnull" json:"sort_order"`
	Title     string    `bun:",notnull" json:"title"`

	// Position data (mutually exclusive based on file type)
	StartPage        *int    `json:"start_page"`         // CBZ: 0-indexed page number
	StartTimestampMs *int64  `json:"start_timestamp_ms"` // M4B: milliseconds from start
	Href             *string `json:"href"`               // EPUB: content document href

	// Relations
	File     *File      `bun:"rel:belongs-to,join:file_id=id" json:"-"`
	Parent   *Chapter   `bun:"rel:belongs-to,join:parent_id=id" json:"-"`
	Children []*Chapter `bun:"rel:has-many,join:id=parent_id" json:"children,omitempty"`
}

type File

type File struct {
	bun.BaseModel `bun:"table:files,alias:f" tstype:"-"`

	ID                       int               `bun:",pk,nullzero" json:"id"`
	CreatedAt                time.Time         `json:"created_at"`
	UpdatedAt                time.Time         `json:"updated_at"`
	LibraryID                int               `bun:",nullzero" json:"library_id"`
	BookID                   int               `bun:",nullzero" json:"book_id"`
	Book                     *Book             `bun:"rel:belongs-to" json:"book" tstype:"Book"`
	Filepath                 string            `bun:",nullzero" json:"filepath"`
	FileType                 string            `bun:",nullzero" json:"file_type" tstype:"FileType"`
	FileRole                 string            `bun:",nullzero,default:'main'" json:"file_role" tstype:"FileRole"`
	FilesizeBytes            int64             `bun:",nullzero" json:"filesize_bytes"`
	FileModifiedAt           *time.Time        `json:"file_modified_at"`
	CoverImageFilename       *string           `json:"cover_image_filename"`
	CoverMimeType            *string           `json:"cover_mime_type"`
	CoverSource              *string           `json:"cover_source" tstype:"DataSource"`
	CoverPage                *int              `json:"cover_page"` // 0-indexed page number for CBZ cover, NULL for EPUB/M4B
	Name                     *string           `json:"name"`
	NameSource               *string           `json:"name_source" tstype:"DataSource"`
	PageCount                *int              `json:"page_count"` // Number of pages for CBZ files, NULL for EPUB/M4B
	AudiobookDurationSeconds *float64          `json:"audiobook_duration_seconds"`
	AudiobookBitrateBps      *int              `json:"audiobook_bitrate_bps"`
	AudiobookCodec           *string           `json:"audiobook_codec"`
	Narrators                []*Narrator       `bun:"rel:has-many,join:id=file_id" json:"narrators,omitempty" tstype:"Narrator[]"`
	NarratorSource           *string           `json:"narrator_source" tstype:"DataSource"`
	Identifiers              []*FileIdentifier `bun:"rel:has-many,join:id=file_id" json:"identifiers,omitempty" tstype:"FileIdentifier[]"`
	IdentifierSource         *string           `json:"identifier_source" tstype:"DataSource"`
	Chapters                 []*Chapter        `bun:"rel:has-many,join:id=file_id" json:"chapters,omitempty" tstype:"Chapter[]"`
	URL                      *string           `json:"url"`
	URLSource                *string           `json:"url_source" tstype:"DataSource"`
	ReleaseDate              *time.Time        `json:"release_date"`
	ReleaseDateSource        *string           `json:"release_date_source" tstype:"DataSource"`
	PublisherID              *int              `json:"publisher_id"`
	PublisherSource          *string           `json:"publisher_source" tstype:"DataSource"`
	Publisher                *Publisher        `bun:"rel:belongs-to,join:publisher_id=id" json:"publisher,omitempty" tstype:"Publisher"`
	ImprintID                *int              `json:"imprint_id"`
	ImprintSource            *string           `json:"imprint_source" tstype:"DataSource"`
	Imprint                  *Imprint          `bun:"rel:belongs-to,join:imprint_id=id" json:"imprint,omitempty" tstype:"Imprint"`
	ChapterSource            *string           `json:"chapter_source" tstype:"DataSource"`
}

func (*File) CoverExtension

func (f *File) CoverExtension() string

type FileIdentifier

type FileIdentifier struct {
	bun.BaseModel `bun:"table:file_identifiers,alias:fi" tstype:"-"`

	ID        int       `bun:",pk,nullzero" json:"id"`
	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
	FileID    int       `bun:",nullzero" json:"file_id"`
	Type      string    `bun:",nullzero" json:"type" tstype:"IdentifierType"`
	Value     string    `bun:",nullzero" json:"value"`
	Source    string    `bun:",nullzero" json:"source" tstype:"DataSource"`
}

type Genre

type Genre struct {
	bun.BaseModel `bun:"table:genres,alias:g" tstype:"-"`

	ID        int       `bun:",pk,nullzero" json:"id"`
	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
	LibraryID int       `bun:",nullzero" json:"library_id"`
	Name      string    `bun:",nullzero" json:"name"`
	BookCount int       `bun:",scanonly" json:"book_count"`
}

type Imprint

type Imprint struct {
	bun.BaseModel `bun:"table:imprints,alias:imp" tstype:"-"`

	ID        int       `bun:",pk,nullzero" json:"id"`
	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
	LibraryID int       `bun:",nullzero" json:"library_id"`
	Name      string    `bun:",nullzero" json:"name"`
	FileCount int       `bun:",scanonly" json:"file_count"`
}

type Job

type Job struct {
	bun.BaseModel `bun:"table:jobs,alias:j" tstype:"-"`

	ID         int         `bun:",pk,nullzero" json:"id"`
	CreatedAt  time.Time   `json:"created_at"`
	UpdatedAt  time.Time   `json:"updated_at"`
	Type       string      `bun:",nullzero" json:"type" tstype:"JobType"`
	Status     string      `bun:",nullzero" json:"status" tstype:"JobStatus"`
	Data       string      `bun:",nullzero" json:"-"`
	DataParsed interface{} `bun:"-" json:"data" tstype:"JobExportData | JobScanData"`
	Progress   int         `json:"progress"`
	ProcessID  *string     `json:"process_id,omitempty"`
	LibraryID  *int        `json:"library_id,omitempty"`
}

func (*Job) UnmarshalData

func (job *Job) UnmarshalData() error

type JobExportData

type JobExportData struct{}

type JobLog

type JobLog struct {
	bun.BaseModel `bun:"table:job_logs,alias:jl" tstype:"-"`

	ID         int       `bun:",pk,nullzero" json:"id"`
	CreatedAt  time.Time `json:"created_at"`
	JobID      int       `bun:",nullzero" json:"job_id"`
	Level      string    `bun:",nullzero" json:"level" tstype:"JobLogLevel"`
	Message    string    `bun:",nullzero" json:"message"`
	Plugin     *string   `json:"plugin,omitempty"`
	Data       *string   `json:"data,omitempty"`
	StackTrace *string   `json:"stack_trace,omitempty"`
}

type JobScanData

type JobScanData struct{}

type Library

type Library struct {
	bun.BaseModel `bun:"table:libraries,alias:l" tstype:"-"`

	ID                       int            `bun:",pk,nullzero" json:"id"`
	CreatedAt                time.Time      `json:"created_at"`
	UpdatedAt                time.Time      `json:"updated_at"`
	Name                     string         `bun:",nullzero" json:"name"`
	OrganizeFileStructure    bool           `json:"organize_file_structure"`
	CoverAspectRatio         string         `bun:",nullzero" json:"cover_aspect_ratio"`
	DownloadFormatPreference string         `bun:",nullzero,default:'original'" json:"download_format_preference"`
	LibraryPaths             []*LibraryPath `bun:"rel:has-many" json:"library_paths,omitempty" tstype:"LibraryPath[]"`
	DeletedAt                *time.Time     `json:"deleted_at,omitempty"`
}

type LibraryPath

type LibraryPath struct {
	bun.BaseModel `bun:"table:library_paths,alias:lp" tstype:"-"`

	ID        int       `bun:",pk,nullzero" json:"id"`
	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
	LibraryID int       `bun:",nullzero" json:"library_id"`
	Filepath  string    `bun:",nullzero" json:"filepath"`
}

type LibraryPlugin

type LibraryPlugin struct {
	bun.BaseModel `bun:"table:library_plugins,alias:lp" tstype:"-"`

	LibraryID int    `bun:",pk" json:"library_id"`
	HookType  string `bun:",pk" json:"hook_type" tstype:"PluginHookType"`
	Scope     string `bun:",pk" json:"scope"`
	PluginID  string `bun:",pk" json:"plugin_id"`
	Enabled   bool   `bun:",notnull" json:"enabled"`
	Position  int    `bun:",notnull" json:"position"`
}

type LibraryPluginCustomization

type LibraryPluginCustomization struct {
	bun.BaseModel `bun:"table:library_plugin_customizations,alias:lpc" tstype:"-"`

	LibraryID int    `bun:",pk" json:"library_id"`
	HookType  string `bun:",pk" json:"hook_type" tstype:"PluginHookType"`
}

type LibraryPluginFieldSetting added in v0.0.10

type LibraryPluginFieldSetting struct {
	bun.BaseModel `bun:"table:library_plugin_field_settings,alias:lpfs" tstype:"-"`

	LibraryID int    `bun:",pk" json:"library_id"`
	Scope     string `bun:",pk" json:"scope"`
	PluginID  string `bun:",pk" json:"plugin_id"`
	Field     string `bun:",pk" json:"field"`
	Enabled   bool   `bun:",notnull" json:"enabled"`
}

LibraryPluginFieldSetting stores per-library field overrides. Only rows with explicit overrides are stored; absence means use global default.

type List

type List struct {
	bun.BaseModel `bun:"table:lists,alias:l" tstype:"-"`

	ID          int       `bun:",pk,nullzero" json:"id"`
	CreatedAt   time.Time `json:"created_at"`
	UpdatedAt   time.Time `json:"updated_at"`
	UserID      int       `bun:",nullzero" json:"user_id"`
	User        *User     `bun:"rel:belongs-to,join:user_id=id" json:"user,omitempty" tstype:"User"`
	Name        string    `bun:",nullzero" json:"name"`
	Description *string   `json:"description"`
	IsOrdered   bool      `json:"is_ordered"`
	DefaultSort string    `bun:",nullzero" json:"default_sort"`

	// Relations
	ListBooks  []*ListBook  `bun:"rel:has-many,join:id=list_id" json:"list_books,omitempty" tstype:"ListBook[]"`
	ListShares []*ListShare `bun:"rel:has-many,join:id=list_id" json:"list_shares,omitempty" tstype:"ListShare[]"`
}

type ListBook

type ListBook struct {
	bun.BaseModel `bun:"table:list_books,alias:lb" tstype:"-"`

	ID            int       `bun:",pk,nullzero" json:"id"`
	ListID        int       `bun:",nullzero" json:"list_id"`
	List          *List     `bun:"rel:belongs-to,join:list_id=id" json:"list,omitempty" tstype:"List"`
	BookID        int       `bun:",nullzero" json:"book_id"`
	Book          *Book     `bun:"rel:belongs-to,join:book_id=id" json:"book,omitempty" tstype:"Book"`
	AddedAt       time.Time `json:"added_at"`
	AddedByUserID *int      `json:"added_by_user_id"`
	AddedByUser   *User     `bun:"rel:belongs-to,join:added_by_user_id=id" json:"added_by_user,omitempty" tstype:"User"`
	SortOrder     *int      `json:"sort_order"`
}

type ListShare

type ListShare struct {
	bun.BaseModel `bun:"table:list_shares,alias:ls" tstype:"-"`

	ID             int       `bun:",pk,nullzero" json:"id"`
	ListID         int       `bun:",nullzero" json:"list_id"`
	List           *List     `bun:"rel:belongs-to,join:list_id=id" json:"list,omitempty" tstype:"List"`
	UserID         int       `bun:",nullzero" json:"user_id"`
	User           *User     `bun:"rel:belongs-to,join:user_id=id" json:"user,omitempty" tstype:"User"`
	Permission     string    `bun:",nullzero" json:"permission"`
	CreatedAt      time.Time `json:"created_at"`
	SharedByUserID *int      `json:"shared_by_user_id"`
	SharedByUser   *User     `bun:"rel:belongs-to,join:shared_by_user_id=id" json:"shared_by_user,omitempty" tstype:"User"`
}

type Narrator

type Narrator struct {
	bun.BaseModel `bun:"table:narrators,alias:n" tstype:"-"`

	ID        int     `bun:",pk,nullzero" json:"id"`
	FileID    int     `bun:",nullzero" json:"file_id"`
	PersonID  int     `bun:",nullzero" json:"person_id"`
	Person    *Person `bun:"rel:belongs-to,join:person_id=id" json:"person,omitempty" tstype:"Person"`
	SortOrder int     `bun:",nullzero" json:"sort_order"`
}

type Permission

type Permission struct {
	bun.BaseModel `bun:"table:permissions,alias:p" tstype:"-"`

	ID        int    `bun:",pk,nullzero" json:"id"`
	RoleID    int    `json:"role_id"`
	Resource  string `json:"resource"`
	Operation string `json:"operation"`
}

type Person

type Person struct {
	bun.BaseModel `bun:"table:persons,alias:p" tstype:"-"`

	ID             int       `bun:",pk,nullzero" json:"id"`
	CreatedAt      time.Time `json:"created_at"`
	UpdatedAt      time.Time `json:"updated_at"`
	LibraryID      int       `bun:",nullzero" json:"library_id"`
	Name           string    `bun:",nullzero" json:"name"`
	SortName       string    `bun:",notnull" json:"sort_name"`
	SortNameSource string    `bun:",notnull" json:"sort_name_source" tstype:"DataSource"`
}

type Plugin

type Plugin struct {
	bun.BaseModel `bun:"table:plugins,alias:p" tstype:"-"`

	Scope                  string       `bun:",pk" json:"scope"`
	ID                     string       `bun:",pk" json:"id"`
	Name                   string       `bun:",notnull" json:"name"`
	Version                string       `bun:",notnull" json:"version"`
	Description            *string      `json:"description"`
	Author                 *string      `json:"author"`
	Homepage               *string      `json:"homepage"`
	Status                 PluginStatus `bun:",notnull,default:0" json:"status"`
	AutoUpdate             bool         `bun:",notnull,default:true" json:"auto_update"`
	RepositoryScope        *string      `json:"repository_scope"`
	RepositoryURL          *string      `json:"repository_url"`
	InstalledAt            time.Time    `bun:",notnull" json:"installed_at"`
	UpdatedAt              *time.Time   `json:"updated_at"`
	LoadError              *string      `json:"load_error"`
	UpdateAvailableVersion *string      `json:"update_available_version"`
}

type PluginConfig

type PluginConfig struct {
	bun.BaseModel `bun:"table:plugin_configs,alias:pc" tstype:"-"`

	Scope    string  `bun:",pk" json:"scope"`
	PluginID string  `bun:",pk" json:"plugin_id"`
	Key      string  `bun:",pk" json:"key"`
	Value    *string `json:"value"`
}

type PluginFieldSetting added in v0.0.10

type PluginFieldSetting struct {
	bun.BaseModel `bun:"table:plugin_field_settings,alias:pfs" tstype:"-"`

	Scope    string `bun:",pk" json:"scope"`
	PluginID string `bun:",pk" json:"plugin_id"`
	Field    string `bun:",pk" json:"field"`
	Enabled  bool   `bun:",notnull" json:"enabled"`
}

PluginFieldSetting stores global field enable/disable settings for a plugin. Absence of a row means the field is enabled (default).

type PluginIdentifierType

type PluginIdentifierType struct {
	bun.BaseModel `bun:"table:plugin_identifier_types,alias:pit" tstype:"-"`

	ID          string  `bun:",pk" json:"id"`
	Scope       string  `bun:",notnull" json:"scope"`
	PluginID    string  `bun:",notnull" json:"plugin_id"`
	Name        string  `bun:",notnull" json:"name"`
	URLTemplate *string `json:"url_template"`
	Pattern     *string `json:"pattern"`
}

type PluginOrder

type PluginOrder struct {
	bun.BaseModel `bun:"table:plugin_order,alias:po" tstype:"-"`

	HookType string `bun:",pk" json:"hook_type" tstype:"PluginHookType"`
	Scope    string `bun:",pk" json:"scope"`
	PluginID string `bun:",pk" json:"plugin_id"`
	Position int    `bun:",notnull" json:"position"`
}

type PluginRepository

type PluginRepository struct {
	bun.BaseModel `bun:"table:plugin_repositories,alias:pr" tstype:"-"`

	URL           string     `bun:",pk" json:"url"`
	Scope         string     `bun:",notnull,unique" json:"scope"`
	Name          *string    `json:"name"`
	IsOfficial    bool       `bun:",notnull" json:"is_official"`
	Enabled       bool       `bun:",notnull" json:"enabled"`
	LastFetchedAt *time.Time `json:"last_fetched_at"`
	FetchError    *string    `json:"fetch_error"`
}

type PluginStatus added in v0.0.18

type PluginStatus int

PluginStatus represents the lifecycle state of a plugin.

const (
	// PluginStatusActive means the plugin is running normally.
	PluginStatusActive PluginStatus = 0
	// PluginStatusDisabled means the user has disabled the plugin.
	PluginStatusDisabled PluginStatus = -1
	// PluginStatusMalfunctioned means the plugin failed to load (LoadError has details).
	PluginStatusMalfunctioned PluginStatus = -2
	// PluginStatusNotSupported means the plugin's minShishoVersion is incompatible.
	PluginStatusNotSupported PluginStatus = -3
)

type Publisher

type Publisher struct {
	bun.BaseModel `bun:"table:publishers,alias:pub" tstype:"-"`

	ID        int       `bun:",pk,nullzero" json:"id"`
	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
	LibraryID int       `bun:",nullzero" json:"library_id"`
	Name      string    `bun:",nullzero" json:"name"`
	FileCount int       `bun:",scanonly" json:"file_count"`
}

type Role

type Role struct {
	bun.BaseModel `bun:"table:roles,alias:r" tstype:"-"`

	ID          int           `bun:",pk,nullzero" json:"id"`
	CreatedAt   time.Time     `json:"created_at"`
	UpdatedAt   time.Time     `json:"updated_at"`
	Name        string        `bun:",nullzero" json:"name"`
	IsSystem    bool          `json:"is_system"`
	Permissions []*Permission `bun:"rel:has-many,join:id=role_id" json:"permissions,omitempty" tstype:"Permission[]"`
}

func (*Role) HasPermission

func (r *Role) HasPermission(resource, operation string) bool

HasPermission checks if the role has a specific permission.

type Series

type Series struct {
	bun.BaseModel `bun:"table:series,alias:s" tstype:"-"`

	ID                 int           `bun:",pk,nullzero" json:"id"`
	CreatedAt          time.Time     `json:"created_at"`
	UpdatedAt          time.Time     `json:"updated_at"`
	DeletedAt          *time.Time    `bun:",soft_delete" json:"-"`
	LibraryID          int           `bun:",nullzero" json:"library_id"`
	Library            *Library      `bun:"rel:belongs-to" json:"library,omitempty" tstype:"Library"`
	Name               string        `bun:",nullzero" json:"name"`
	NameSource         string        `bun:",nullzero" json:"name_source" tstype:"DataSource"`
	SortName           string        `bun:",notnull" json:"sort_name"`
	SortNameSource     string        `bun:",notnull" json:"sort_name_source" tstype:"DataSource"`
	Description        *string       `json:"description,omitempty"`
	CoverImageFilename *string       `json:"cover_image_filename,omitempty"`
	BookSeries         []*BookSeries `bun:"rel:has-many" json:"book_series,omitempty" tstype:"BookSeries[]"`
	BookCount          int           `bun:",scanonly" json:"book_count"`
}

type Tag

type Tag struct {
	bun.BaseModel `bun:"table:tags,alias:t" tstype:"-"`

	ID        int       `bun:",pk,nullzero" json:"id"`
	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
	LibraryID int       `bun:",nullzero" json:"library_id"`
	Name      string    `bun:",nullzero" json:"name"`
	BookCount int       `bun:",scanonly" json:"book_count"`
}

type User

type User struct {
	bun.BaseModel `bun:"table:users,alias:u" tstype:"-"`

	ID                 int       `bun:",pk,nullzero" json:"id"`
	CreatedAt          time.Time `json:"created_at"`
	UpdatedAt          time.Time `json:"updated_at"`
	Username           string    `bun:",nullzero" json:"username"`
	Email              *string   `json:"email,omitempty"`
	PasswordHash       string    `json:"-"` // Never expose password hash
	RoleID             int       `json:"role_id"`
	IsActive           bool      `json:"is_active"`
	MustChangePassword bool      `json:"must_change_password"`

	// Relations
	Role          *Role                `bun:"rel:belongs-to,join:role_id=id" json:"role,omitempty" tstype:"Role"`
	LibraryAccess []*UserLibraryAccess `bun:"rel:has-many,join:id=user_id" json:"library_access,omitempty" tstype:"UserLibraryAccess[]"`
}

func (*User) GetAccessibleLibraryIDs

func (u *User) GetAccessibleLibraryIDs() []int

GetAccessibleLibraryIDs returns the list of library IDs the user can access. Returns nil if user has access to all libraries.

func (*User) HasAllLibraryAccess

func (u *User) HasAllLibraryAccess() bool

HasAllLibraryAccess checks if the user has access to all libraries.

func (*User) HasLibraryAccess

func (u *User) HasLibraryAccess(libraryID int) bool

HasLibraryAccess checks if the user can access a specific library. Returns true if user has access to all libraries (null library_id entry) or has explicit access to the specified library.

func (*User) HasPermission

func (u *User) HasPermission(resource, operation string) bool

HasPermission checks if the user has a specific permission.

type UserLibraryAccess

type UserLibraryAccess struct {
	bun.BaseModel `bun:"table:user_library_access,alias:ula" tstype:"-"`

	ID        int  `bun:",pk,nullzero" json:"id"`
	UserID    int  `json:"user_id"`
	LibraryID *int `json:"library_id"` // null means access to all libraries
}

type UserSettings

type UserSettings struct {
	bun.BaseModel `bun:"table:user_settings,alias:us" tstype:"-"`

	ID                 int       `bun:",pk,autoincrement" json:"id"`
	CreatedAt          time.Time `bun:",nullzero,notnull,default:current_timestamp" json:"created_at"`
	UpdatedAt          time.Time `bun:",nullzero,notnull,default:current_timestamp" json:"updated_at"`
	UserID             int       `bun:",notnull,unique" json:"user_id"`
	ViewerPreloadCount int       `bun:",notnull,default:3" json:"viewer_preload_count"`
	ViewerFitMode      string    `bun:",notnull,default:'fit-height'" json:"viewer_fit_mode" tstype:"FitMode"`
}

func DefaultUserSettings

func DefaultUserSettings() *UserSettings

DefaultUserSettings returns a UserSettings with default values.

Jump to

Keyboard shortcuts

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