package music import ( "arimelody-web/errors" "arimelody-web/model" "arimelody-web/service/validator" "fmt" "time" ) // Hydrates a release with its additional data (credits, tracks, links) func (s *MusicService) fillRelease(release *model.Release) error { credits, err := s.GetReleaseCredits(release.ID) if err != nil { return fmt.Errorf("credits: %s", err) } release.Credits = append(release.Credits, credits...) tracks, err := s.GetReleaseTracks(release.ID) if err != nil { return fmt.Errorf("tracks: %s", err) } release.Tracks = append(release.Tracks, tracks...) links, err := s.GetReleaseLinks(release.ID) if err != nil { return fmt.Errorf("links: %s", err) } release.Links = append(release.Links, links...) return nil } func (s *MusicService) GetAllReleases(onlyVisible bool, limit int) ([]*model.Release, error) { return s.repo.GetAllReleases(onlyVisible, limit) } func (s *MusicService) GetAllFullReleases(onlyVisible bool, limit int) ([]*model.Release, error) { releases, err := s.repo.GetAllReleases(onlyVisible, limit) if err != nil { return nil, err } for _, release := range releases { if err := s.fillRelease(release); err != nil { return nil, err } } return releases, nil } func (s *MusicService) GetReleaseCount(onlyVisible bool) (int, error) { return s.repo.GetReleaseCount(onlyVisible) } func (s *MusicService) GetReleaseByID(id string) (*model.Release, error) { release, err := s.repo.GetReleaseByID(id) if err != nil { return nil, err } if release == nil { return nil, errors.NewNotExistError("Release does not exist") } return release, nil } func (s *MusicService) GetFullReleaseByID(id string) (*model.Release, error) { release, err := s.GetReleaseByID(id) if err != nil { return nil, err } if err := s.fillRelease(release); err != nil { return nil, err } return release, nil } func (s *MusicService) GetReleaseTracks(id string) ([]*model.Track, error) { return s.repo.GetReleaseTracks(id) } func (s *MusicService) GetReleaseCredits(id string) ([]*model.Credit, error) { return s.repo.GetReleaseCredits(id) } func (s *MusicService) GetReleaseLinks(id string) ([]*model.Link, error) { return s.repo.GetReleaseLinks(id) } func (s *MusicService) CreateRelease( id string, title string, releaseType string, releaseDate time.Time, artworkURL string, ) error { if len(id) == 0 { return errors.NewValidationError("Release ID cannot be empty") } if !validator.ValidateID(id) { return errors.NewValidationError("Release ID contains invalid characters") } if len(title) == 0 { return errors.NewValidationError("Release title cannot be empty") } validReleaseType, ok := model.ValidReleaseType(releaseType) if !ok { return errors.NewValidationError("Invalid release type") } if err := s.repo.CreateRelease(id, title, validReleaseType, releaseDate, artworkURL); err != nil { return err } s.log.Printf("Created new release '%s' (%s)", title, id) return nil } func (s *MusicService) UpdateRelease(release *model.Release) error { if len(release.ID) == 0 { return errors.NewValidationError("Release ID cannot be empty") } if !validator.ValidateID(release.ID) { return errors.NewValidationError("Release ID contains invalid characters") } if len(release.Title) == 0 { return errors.NewValidationError("Release title cannot be empty") } if err := s.repo.UpdateRelease(release); err != nil { return err } s.log.Printf("Updated release '%s' (%s)", release.Title, release.ID) return nil } func (s *MusicService) UpdateReleaseID(oldID string, newID string) error { if len(newID) == 0 { return errors.NewValidationError("Release ID cannot be empty") } if !validator.ValidateID(newID) { return errors.NewValidationError("Release ID contains invalid characters") } if err := s.repo.UpdateReleaseID(oldID, newID); err != nil { return err } s.log.Printf("Updated release ID %s to %s", oldID, newID) return nil } func (s *MusicService) UpdateReleaseVisibility(id string, visible bool) error { if err := s.repo.UpdateReleaseVisibility(id, visible); err != nil { return err } s.log.Printf("Updated release '%s' visibility to %t", id, visible) return nil } func (s *MusicService) UpdateReleaseTitle(id string, title string) error { if len(title) == 0 { return errors.NewValidationError("Release title cannot be empty") } if err := s.repo.UpdateReleaseTitle(id, title); err != nil { return err } s.log.Printf("Updated release '%s' title to %s", id, title) return nil } func (s *MusicService) UpdateReleaseDescription(id string, description string) error { if err := s.repo.UpdateReleaseDescription(id, description); err != nil { return err } s.log.Printf("Updated release '%s' description to %s", id, description) return nil } func (s *MusicService) UpdateReleaseType(id string, releaseType string) error { validReleaseType, ok := model.ValidReleaseType(releaseType) if !ok { return errors.NewValidationError("Invalid release type") } if err := s.repo.UpdateReleaseType(id, validReleaseType); err != nil { return err } s.log.Printf("Updated release '%s' type to %s", id, releaseType) return nil } func (s *MusicService) UpdateReleaseDate(id string, releaseDate time.Time) error { if err := s.repo.UpdateReleaseDate(id, releaseDate); err != nil { return err } s.log.Printf("Updated release '%s' date to %s", id, releaseDate.Format(time.RFC3339)) return nil } func (s *MusicService) UpdateReleaseArtwork(id string, artwork string) error { if err := s.repo.UpdateReleaseArtwork(id, artwork); err != nil { return err } s.log.Printf("Updated release '%s' artwork to %s", id, artwork) return nil } func (s *MusicService) UpdateReleaseBuyInfo(id string, buyName string, buyLink string) error { if err := s.repo.UpdateReleaseBuyInfo(id, buyName, buyLink); err != nil { return err } s.log.Printf("Updated release '%s' buy info (name='%s', link='%s')", id, buyName, buyLink) return nil } func (s *MusicService) UpdateReleaseCopyright(id string, copyright string, url string) error { if err := s.repo.UpdateReleaseCopyright(id, copyright, url); err != nil { return err } s.log.Printf("Updated release '%s' copyright (copyright='%s', url='%s')", id, copyright, url) return nil } func (s *MusicService) UpdateReleaseTracks(id string, newTrackIDs []string) error { for _, id := range newTrackIDs { if len(id) == 0 { return errors.NewValidationError("Track IDs cannot be empty") } } if err := s.repo.UpdateReleaseTracks(id, newTrackIDs); err != nil { return err } s.log.Printf("Updated release '%s' tracks (%d tracks)", id, len(newTrackIDs)) return nil } func (s *MusicService) UpdateReleaseCredits(id string, newCredits []*model.Credit) error { if err := s.repo.UpdateReleaseCredits(id, newCredits); err != nil { return err } s.log.Printf("Updated release '%s' credits (%d credits)", id, len(newCredits)) return nil } func (s *MusicService) UpdateReleaseLinks(id string, newLinks []*model.Link) error { for _, link := range newLinks { if len(link.Name) == 0 { return errors.NewValidationError("Link names cannot be empty") } if len(link.URL) == 0 { return errors.NewValidationError("Link URLs cannot be empty") } } if err := s.repo.UpdateReleaseLinks(id, newLinks); err != nil { return err } s.log.Printf("Updated release '%s' links (%d links)", id, len(newLinks)) return nil } func (s *MusicService) DeleteRelease(id string) error { deletedID, err := s.repo.DeleteRelease(id) if err != nil { return err } if deletedID == "" { return errors.NewNotExistError("Release does not exist") } s.log.Printf("Deleted release '%s'", id) return nil }