Documentation ¶
Index ¶
- Variables
- func UpdateRating[U UpdateableKeyTypes](ctx context.Context, rs *RatingStorage, id int64, values []U) (err error)
- type ActorCast
- type Album
- type AlbumArtist
- type Book
- type BookValues
- type Cast
- type City
- type Country
- type DirectorCast
- type Entity
- type Episode
- type Film
- type Genre
- type GenreCharacteristics
- type GenreDescription
- type Group
- type Keyword
- type KeywordStorage
- func (ks *KeywordStorage) AddKeyword(ctx context.Context, keyword string, mediaID uuid.UUID) (err error)
- func (ks *KeywordStorage) CastVote(ctx context.Context, k Keyword) error
- func (ks *KeywordStorage) GetAll(ctx context.Context) (keywords []Keyword, err error)
- func (ks *KeywordStorage) GetKeyword(ctx context.Context, keyword string, mediaID uuid.UUID) (k Keyword, err error)
- func (ks *KeywordStorage) GetKeywordByID(ctx context.Context, id int32) (k Keyword, err error)
- func (ks *KeywordStorage) GetKeywords(ctx context.Context, mediaID uuid.UUID) (keywords []Keyword, err error)
- func (ks *KeywordStorage) RemoveVote(ctx context.Context, k Keyword) error
- type KeywordStorer
- type LangID
- type Media
- type MediaDetails
- type MediaObject
- type MediaService
- type MediaStorage
- func (ms *MediaStorage) Add(ctx context.Context, props *Media) (mediaID *uuid.UUID, err error)
- func (ms *MediaStorage) AddBook(ctx context.Context, book *Book, publisher *Studio) error
- func (ms *MediaStorage) AddCast(ctx context.Context, mediaID uuid.UUID, actors, directors []Person) (castID int64, err error)
- func (ms *MediaStorage) AddCreators(ctx context.Context, id uuid.UUID, creators []Person) error
- func (ms *MediaStorage) AddFilm(ctx context.Context, film *Film) error
- func (ms *MediaStorage) Delete(ctx context.Context, mediaID uuid.UUID) error
- func (ms *MediaStorage) Get(ctx context.Context, id uuid.UUID) (media Media, err error)
- func (ms *MediaStorage) GetAlbumTrackIDs(ctx context.Context, albumID uuid.UUID) ([]uuid.UUID, error)
- func (ms *MediaStorage) GetAlbumTracks(ctx context.Context, albumID uuid.UUID) ([]Track, error)
- func (ms *MediaStorage) GetAll() ([]*interface{}, error)
- func (ms *MediaStorage) GetCast(ctx context.Context, mediaID uuid.UUID) (cast Cast, err error)
- func (ms *MediaStorage) GetGenre(ctx context.Context, kind, lang, name string) (genre *Genre, err error)
- func (ms *MediaStorage) GetGenres(ctx context.Context, kind string, all bool, columns ...string) ([]Genre, error)
- func (ms *MediaStorage) GetImagePath(ctx context.Context, id uuid.UUID) (path string, err error)
- func (ms *MediaStorage) GetKind(ctx context.Context, id uuid.UUID) (string, error)
- func (ms *MediaStorage) GetMediaDetails(ctx context.Context, mediaKind string, id uuid.UUID) (interface{}, error)
- func (ms *MediaStorage) GetRandom(ctx context.Context, count int, blacklistKinds ...string) (mwks map[uuid.UUID]string, err error)
- func (ms *MediaStorage) Update(ctx context.Context, key string, value interface{}, mediaID uuid.UUID) error
- func (ms *MediaStorage) UpdateFilm(ctx context.Context, film *Film) error
- type MediaStorer
- type PeopleStorage
- func (p *PeopleStorage) GetGroup(ctx context.Context, id int32) (Group, error)
- func (p *PeopleStorage) GetGroupName(ctx context.Context, id int32) (Group, error)
- func (p *PeopleStorage) GetID(ctx context.Context, name, kind string) (id int32, err error)
- func (p *PeopleStorage) GetPerson(ctx context.Context, id int64) (Person, error)
- func (p *PeopleStorage) GetPersonNames(ctx context.Context, id int32) (Person, error)
- func (p *PeopleStorage) GetStudio(ctx context.Context, id int32) (*Studio, error)
- type Person
- type Place
- type RatingAverage
- type RatingInput
- type RatingStorage
- func (rs *RatingStorage) Delete(ctx context.Context, id int64) (err error)
- func (rs *RatingStorage) Get(ctx context.Context, id int64) (r Review, err error)
- func (rs *RatingStorage) GetAll() (ratings []*Review, err error)
- func (rs *RatingStorage) GetAverageStars(ctx context.Context, mediaID uuid.UUID) (avgStars float64, err error)
- func (rs *RatingStorage) GetByMediaID(ctx context.Context, mediaID uuid.UUID) (ratings []*Review, err error)
- func (rs *RatingStorage) GetLatest(ctx context.Context, limit int, offset int) (ratings []*Review, err error)
- func (rs *RatingStorage) New(ctx context.Context, rating *RatingInput) error
- type RatingStorer
- type Review
- type Season
- type SecondaryRating
- type SecondaryRatingAverage
- type Studio
- type TVShow
- type Track
- type UpdateableKeyTypes
- type Venue
Constants ¶
This section is empty.
Variables ¶
var BookKeys = []string{
"media_id", "title", "authors",
"genres", "edition", "languages",
}
Functions ¶
func UpdateRating ¶
func UpdateRating[U UpdateableKeyTypes](ctx context.Context, rs *RatingStorage, id int64, values []U) (err error)
Types ¶
type Album ¶
type Album struct { MediaID *uuid.UUID `json:"media_id" db:"media_id,pk,unique"` Name string `json:"name" db:"name"` AlbumArtists AlbumArtist `json:"album_artists" db:"album_artists"` ImagePaths pq.StringArray `json:"image_paths,omitempty"` // we make use of a junction table that utilizes the image IDs ReleaseDate time.Time `json:"release_date" db:"release_date"` Genres []Genre `json:"genres,omitempty" db:"genres"` // Studio Studio `json:"studio,omitempty" db:"studio"` Keywords []Keyword `json:"keywords,omitempty" db:"keywords"` Duration sql.NullTime `json:"duration,omitempty" db:"duration"` Tracks []Track `json:"tracks,omitempty" db:"tracks"` }
type AlbumArtist ¶
type Book ¶
type Book struct { MediaID *uuid.UUID `json:"media_id" db:"media_id,pk,unique"` Title string `json:"title" db:"title"` Authors []Person `json:"author" db:"author"` Publisher Studio `json:"publisher" db:"publisher"` PublicationDate sql.NullTime `json:"publication_date" db:"publication_date"` Genres []Genre `json:"genres" db:"genres"` Keywords pq.StringArray `json:"keywords,omitempty" db:"keywords,omitempty"` Languages []string `json:"languages" db:"languages"` Pages int16 `json:"pages" db:"pages"` ISBN sql.NullString `json:"isbn,omitempty" db:"isbn,unique,omitempty"` ASIN sql.NullString `json:"asin,omitempty" db:"asin,unique,omitempty"` Cover sql.NullString `json:"cover,omitempty" db:"cover,omitempty"` Summary string `json:"summary" db:"summary"` }
type DirectorCast ¶
type Episode ¶
type Episode struct { MediaID *uuid.UUID `json:"media_id" db:"media_id,pk,unique"` ShowID *uuid.UUID `json:"show_id" db:"show_id,pk,unique"` SeasonID *uuid.UUID `json:"season_id" db:"season_id,pk,unique"` Number uint16 `json:"number" db:"number,autoinc"` Title string `json:"title" db:"title"` Season uint16 `json:"season" db:"season"` Episode uint16 `json:"episode" db:"episode"` AirDate time.Time `json:"air_date" db:"air_date"` Duration time.Duration `json:"duration" db:"duration"` Languages []string `json:"languages" db:"languages"` Plot string `json:"plot" db:"plot"` }
type Film ¶
type Film struct { MediaID *uuid.UUID `json:"media_id" db:"media_id,pk,unique"` Title string `json:"title" db:"title"` Cast Cast `json:"cast"` // this data is stored in the people schema, so no db tag ReleaseDate sql.NullTime `json:"release_date" db:"release_date"` Duration sql.NullTime `json:"duration" db:"duration"` Synopsis sql.NullString `json:"synopsis" db:"synopsis"` // TODO: check if nullFloat64 is the right type for this Rating sql.NullFloat64 `json:"rating"` // stored in the reviews.rating table, can be queried with a join on media ID }
nolint:musttag
func (*Film) GetPosterPath ¶
type Genre ¶
type Genre struct { ID int64 `json:"id" db:"id,pk,autoinc"` Kinds pq.StringArray `json:"kind" db:"kind" enum:"music,film,tv,book,game"` Name string `json:"name" db:"name"` Description []GenreDescription `json:"description,omitempty" db:"-"` // DescLong string `json:"desc_long" db:"desc_long"` Characteristics []string `json:"keywords" db:"-"` ParentGenreID *int64 `json:"parent_genre omitempty" db:"parent,omitempty"` Children []int64 `json:"children,omitempty" db:"children,omitempty"` }
Genre does not hage a UUID due to parent-child relationships
type GenreCharacteristics ¶ added in v0.8.14
type GenreCharacteristics struct { ID int64 `json:"id" db:"id,pk,autoinc"` Name string `json:"name" db:"name"` Descripion sql.NullString `json:"description,omitempty" db:"description"` }
type GenreDescription ¶ added in v0.8.14
type Group ¶
type Group struct { ID int32 `json:"id,omitempty" db:"id"` Locations []Place `json:"locations,omitempty" db:"locations"` Name string `json:"name" db:"name"` Active bool `json:"active,omitempty" db:"active"` Formed sql.NullTime `json:"formed,omitempty" db:"formed"` Disbanded sql.NullTime `json:"disbanded,omitempty" db:"disbanded"` Website sql.NullString `json:"website,omitempty" db:"website"` Photos []string `json:"photos,omitempty" db:"photos"` Works []*uuid.UUID `json:"works,omitempty" db:"works"` Members []Person `json:"members,omitempty" db:"members"` PrimaryGenre Genre `json:"primary_genre,omitempty" db:"primary_genre_id"` SecondaryGenres []Genre `json:"genres,omitempty" db:"genres"` Kind string `json:"kind,omitempty" db:"kind"` // Orchestra, Choir, Ensemble, Collective, etc. Added time.Time `json:"added" db:"added"` Modified sql.NullTime `json:"modified,omitempty" db:"modified"` Wikipedia sql.NullString `json:"wikipedia,omitempty" db:"wikipedia"` Bandcamp sql.NullString `json:"bandcamp,omitempty" db:"bandcamp"` Soundcloud sql.NullString `json:"soundcloud,omitempty" db:"soundcloud"` Bio sql.NullString `json:"bio,omitempty" db:"bio"` }
type KeywordStorage ¶
type KeywordStorage struct {
// contains filtered or unexported fields
}
func NewKeywordStorage ¶
func NewKeywordStorage(db *sqlx.DB, log *zerolog.Logger) *KeywordStorage
func (*KeywordStorage) AddKeyword ¶
func (ks *KeywordStorage) AddKeyword(ctx context.Context, keyword string, mediaID uuid.UUID) (err error)
func (*KeywordStorage) CastVote ¶
func (ks *KeywordStorage) CastVote(ctx context.Context, k Keyword) error
func (*KeywordStorage) GetAll ¶
func (ks *KeywordStorage) GetAll(ctx context.Context) (keywords []Keyword, err error)
func (*KeywordStorage) GetKeyword ¶
func (*KeywordStorage) GetKeywordByID ¶
func (*KeywordStorage) GetKeywords ¶
func (ks *KeywordStorage) GetKeywords(ctx context.Context, mediaID uuid.UUID) (keywords []Keyword, err error)
func (*KeywordStorage) RemoveVote ¶
func (ks *KeywordStorage) RemoveVote(ctx context.Context, k Keyword) error
type KeywordStorer ¶
type KeywordStorer interface { CastVote(ctx context.Context, k Keyword) error RemoveVote(ctx context.Context, k Keyword) error AddKeyword(ctx context.Context, k Keyword) error GetKeyword(ctx context.Context, mediaID uuid.UUID) (Keyword, error) GetKeywords(ctx context.Context, mediaID uuid.UUID) ([]Keyword, error) }
type LangID ¶
type LangID int16
const ( English LangID = iota Spanish French German Chinese Japanese Korean Arabic Hebrew Hindi Polish Russian Czech Dutch Greek Italian Swedish Turkish Norwegian Portuguese Finnish Thai Indonesian Vietnamese Farsi Tagalog Swahili Serbian Croatian Bosnian Slovenian Slovak Macedonian Albanian Bulgarian Romanian Hungarian Latvian Lithuanian Estonian Ukrainian Belarusian Malay Malayalam Tamil Telugu Kannada Marathi Gujarati Bengali Punjabi Urdu Mongolian Amharic Icelandic Maltese Unknown Others )
func ReverseLookupLangID ¶
ReverseLookupLangID takes a language name as input and returns the corresponding LangID. If the language name is not found, it returns an error.
type Media ¶
type Media struct { ID uuid.UUID `json:"id" db:"id,pk,unique"` Title string `json:"title" db:"title"` Kind string `json:"kind" db:"kind"` Created time.Time `json:"keywords,omitempty" db:"created"` Creator sql.NullInt32 `json:"creator,omitempty" db:"creator"` Creators []Person `json:"creators,omitempty"` // no db tag, we're using a junction table Added time.Time `json:"added,omitempty" db:"added"` Modified sql.NullTime `json:"modified,omitempty" db:"modified"` }
nolint:musttag // false positive, can only annotate fields, not types
type MediaDetails ¶
type MediaDetails struct { Kind string `json:"kind" db:"kind"` Details interface{} `json:"details" db:"details"` }
type MediaService ¶
type MediaService interface {
IsMedia() bool // dummy placeholder so that we can have somewhat idiomatic parametric polymorphism
}
type MediaStorage ¶
type MediaStorage struct { Log *zerolog.Logger Ps *PeopleStorage // contains filtered or unexported fields }
func NewMediaStorage ¶
func (*MediaStorage) Add ¶
Add is a generic method that adds an object to the media.media table. It needs to be run BEFORE the object is added to its respective table, since it needs the media ID to be generated first.
func (*MediaStorage) AddCreators ¶
func (*MediaStorage) Get ¶
Get scans into a complete Media struct In most cases though, all we need is an intermediate, partial instance with the UUID and Kind fields to be passed to GetMediaDetails
func (*MediaStorage) GetAlbumTrackIDs ¶ added in v0.7.0
func (*MediaStorage) GetAlbumTracks ¶ added in v0.7.0
GetAlbumTracks retrieves the full metadata of given album's tracks based on the album ID
func (*MediaStorage) GetGenres ¶ added in v0.8.14
func (ms *MediaStorage) GetGenres(ctx context.Context, kind string, all bool, columns ...string) ([]Genre, error)
GetGenres returns all genres for specified media type. parameter all specifies whether to return all genres or only top-level ones. variadic argument columns specifies which columns to return. In HTTP layer, columns are specified either in the JSON request body (as an array of strings) The name column can also be accessed with `names_only` boolean query parameter. Fetching of all genres is specified by the `all` query parameter (which does not require a value).
func (*MediaStorage) GetImagePath ¶
func (*MediaStorage) GetMediaDetails ¶
func (*MediaStorage) GetRandom ¶
func (ms *MediaStorage) GetRandom(ctx context.Context, count int, blacklistKinds ...string) ( mwks map[uuid.UUID]string, err error, )
mwks - media IDs with their corresponding kind
type MediaStorer ¶
type PeopleStorage ¶
type PeopleStorage struct {
// contains filtered or unexported fields
}
func NewPeopleStorage ¶
func NewPeopleStorage(dbConn *sqlx.DB, logger *zerolog.Logger) *PeopleStorage
func (*PeopleStorage) GetGroupName ¶
func (*PeopleStorage) GetPersonNames ¶
type Person ¶
type Person struct { ID int32 `json:"id,omitempty" db:"id,pk,unique,autoincrement"` FirstName string `json:"first_name" db:"first_name"` OtherNames pq.StringArray `json:"other_names,omitempty" db:"other_names"` LastName string `json:"last_name" db:"last_name"` NickNames pq.StringArray `json:"nick_names,omitempty" db:"nick_names"` Roles pq.StringArray `json:"roles,omitempty" db:"roles"` Works []*uuid.UUID `json:"works,omitempty" db:"works"` Birth sql.NullTime `json:"birth,omitempty" db:"birth"` // DOB can also be unknown Death sql.NullTime `json:"death,omitempty" db:"death"` Website sql.NullString `json:"website,omitempty" db:"website"` Bio sql.NullString `json:"bio,omitempty" db:"bio"` Photos pq.StringArray `json:"photos,omitempty" db:"photos"` Hometown Place `json:"hometown,omitempty" db:"hometown"` Residence Place `json:"residence,omitempty" db:"residence"` Added time.Time `json:"added,omitempty" db:"added"` Modified sql.NullTime `json:"modified,omitempty" db:"modified"` }
type RatingAverage ¶ added in v0.7.0
type RatingAverage struct { BaseRatingScore float64 `json:"base_rating_score" db:"base_rating_score"` //nolint: revive SecondaryRatingTypes *[]string `` /* 153-byte string literal not displayed */ SecondaryRatingAverages []SecondaryRatingAverage `json:"secondary_rating_score" db:"secondary_rating_score"` }
rating average is a helper, "meta"-type so that the averages retrieved are more concise
type RatingInput ¶
type RatingInput struct { // TODO: allow for setting dynamic rating scales NumStars int8 `json:"numstars" binding:"required" validate:"min=0,max=10" error:"numstars must be between 1 and 15" db:"stars"` Comment string `json:"comment,omitempty" db:"comment"` Topic string `json:"topic,omitempty" db:"topic"` Attribution string `json:"attribution,omitempty" db:"attribution"` UserID uint32 `json:"userid" db:"user_id"` MediaID uuid.UUID `json:"mediaid" db:"media_id"` }
nolint: revive
type RatingStorage ¶
type RatingStorage struct {
// contains filtered or unexported fields
}
func NewRatingStorage ¶
func NewRatingStorage(db *sqlx.DB, log *zerolog.Logger) *RatingStorage
func (*RatingStorage) Delete ¶
func (rs *RatingStorage) Delete(ctx context.Context, id int64) (err error)
func (*RatingStorage) GetAll ¶
func (rs *RatingStorage) GetAll() (ratings []*Review, err error)
func (*RatingStorage) GetAverageStars ¶
func (rs *RatingStorage) GetAverageStars(ctx context.Context, mediaID uuid.UUID, ) (avgStars float64, err error)
func (*RatingStorage) GetByMediaID ¶
func (rs *RatingStorage) GetByMediaID(ctx context.Context, mediaID uuid.UUID) (ratings []*Review, err error)
func (*RatingStorage) GetLatest ¶
func (rs *RatingStorage) GetLatest(ctx context.Context, limit int, offset int) (ratings []*Review, err error)
GetLatestRatings retrieves the latest reviews for all media items. The limit and offset parameters are used for pagination.
func (*RatingStorage) New ¶
func (rs *RatingStorage) New(ctx context.Context, rating *RatingInput) error
type RatingStorer ¶
type RatingStorer interface { New(ri *RatingInput) error Get(ctx context.Context, ID int64) (*Review, error) GetAll() ([]*Review, error) GetByMediaID(ctx context.Context, mediaID uuid.UUID) ([]*Review, error) }
Update is not present, because methods cannot have type parameters
type Review ¶ added in v0.7.0
type Review struct { ID int64 `json:"_key" db:"id,pk"` CreatedAt time.Time `json:"created_at" db:"created_at"` NumStars int8 `json:"numstars" binding:"required" validate:"min=0,max=10" error:"numstars must be between 1 and 10" db:"stars" ` Comment string `json:"comment,omitempty" db:"comment"` Topic string `json:"topic,omitempty" db:"topic"` Attribution string `json:"attribution,omitempty" db:"attribution"` UserID uint32 `json:"userid" db:"user_id"` MediaID uuid.UUID `json:"mediaid" db:"media_id"` SecondaryRatings []*SecondaryRating `json:"secondary_ratings,omitempty" db:"secondary_ratings"` }
nolint: revive
type SecondaryRating ¶ added in v0.7.0
type SecondaryRating struct { ID int64 `json:"_key" db:"id,pk"` MediaID *uuid.UUID `json:"media_id" db:"media_id"` Kind string `json:"kind" validate:"required,oneof=track plotline soundtrack acting scenography scenario theme" db:"kind"` NumStars int8 `json:"numstars" binding:"required" validate:"min=1,max=10,error='numstars must be between 1 and 10'" db:"stars"` UserID uint32 `json:"userid" db:"user_id"` }
TODO: add migration nolint: revive
type SecondaryRatingAverage ¶ added in v0.7.0
type SecondaryRatingAverage struct { MediaID uuid.UUID `json:"_key" db:"media_id,pk"` MediaKind string `json:"media_kind" db:"media_kind"` Score float64 `json:"score,omitempty" db:"score"` }
TODO: add migration (if needed) SecondaryRatingAverages is a map of (secondary rating's) kind to it's value
type Studio ¶
type Studio struct { ID int32 `json:"id" db:"id,pk,serial,unique"` Name string `json:"name" db:"name"` Active bool `json:"active" db:"active"` City *City `json:"city,omitempty" db:"city"` Artists []Person `json:"artists,omitempty" db:"artists"` Works Media `json:"works,omitempty" db:"works"` IsFilm bool `json:"is_film" db:"is_film"` IsMusic bool `json:"is_music" db:"is_music"` IsTV bool `json:"is_tv" db:"is_tv"` IsPublishing bool `json:"is_publishing" db:"is_publishing"` IsGame bool `json:"is_game" db:"is_game"` }
type TVShow ¶
type TVShow struct { MediaID *uuid.UUID `json:"media_id" db:"media_id,pk,unique"` Title string `json:"title" db:"title"` Cast Cast `json:"cast" db:"cast"` Year int `json:"year" db:"year"` Active bool `json:"active" db:"active"` Seasons []Season `json:"seasons" db:"seasons"` Studio Studio `json:"studio" db:"studio"` }
type Track ¶
type Track struct { MediaID *uuid.UUID `json:"media_id" db:"media_id,pk,unique"` Name string `json:"name" db:"name"` AlbumID *uuid.UUID `json:"album_id" db:"album"` // Artists mo.Either[[]Person, []Group] `json:"artists" db:"artists"` Duration time.Time `json:"duration" db:"duration"` Lyrics string `json:"lyrics,omitempty" db:"lyrics"` Number int16 `json:"track_number" db:"track_number"` }
type UpdateableKeyTypes ¶
type Venue ¶
type Venue struct { UUID uuid.UUID `json:"uuid" db:"uuid,pk"` Name string `json:"name" db:"name"` Active bool `json:"active" db:"active"` Street string `json:"street" db:"street"` Zip string `json:"zip" db:"zip"` Unit string `json:"unit" db:"unit"` City *City `json:"city" db:"city"` Country *Country `json:"country" db:"country"` }