Newer
Older
//
// tank
//
// Import and Playlist Daemon for autoradio project
//
//
// Copyright (C) 2017-2019 Christian Pointner <equinox@helsinki.at>
//
// This file is part of tank.
//
// tank is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// tank is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with tank. If not, see <http://www.gnu.org/licenses/>.
//
package store
import (
"fmt"
"net/url"
"strconv"
"github.com/jinzhu/gorm"
)
func (p *Playlist) BeforeSave() error {
for idx := range p.Entries {
p.Entries[idx].LineNum = uint(idx)
if p.Entries[idx].File != nil {
p.Entries[idx].URI = "" // this will be regenerated in AfterFind()
} else if p.Entries[idx].URI != "" {
uri, err := url.Parse(p.Entries[idx].URI)
if err != nil {
return fmt.Errorf("playlist entry #%d is invalid: %v", idx, err)
}
if uri.Scheme == FileURIScheme {
if uri.Host == "" || uri.Path == "" {
return fmt.Errorf("playlist entry #%d is invalid: uri must be in the format %s://<show>/<file-id>", idx, FileURIScheme)
fileID, err := strconv.ParseUint(strings.TrimPrefix(uri.Path, "/"), 10, 64)
if err != nil {
return fmt.Errorf("playlist entry #%d is invalid: %v", idx, err)
}
p.Entries[idx].File = &File{ID: fileID, ShowName: uri.Host}
p.Entries[idx].URI = "" // this will be regenerated in AfterFind()
}
} else {
return fmt.Errorf("playlist entry #%d is invalid, entries must either contain a File or have a URI set", idx)
}
func (p *Playlist) AfterSave(tx *gorm.DB) error {
return tx.Preload("Entries.File").First(p, p.ID).Error
}
func (p *Playlist) AfterFind() error {
for idx := range p.Entries {
if p.Entries[idx].File != nil {
urihost := p.Entries[idx].File.ShowName
uripath := strconv.FormatUint(p.Entries[idx].File.ID, 10)
uri := url.URL{Scheme: FileURIScheme, Host: urihost, Path: uripath}
p.Entries[idx].URI = uri.String()
}
}
return nil
func (st *Store) ListPlaylists(show string) (playlists Playlists, err error) {
err = st.db.Where("show_name = ?", show).Preload("Entries", func(db *gorm.DB) *gorm.DB {
return db.Order("playlist_entries.line_num asc")
}).Preload("Entries.File").Find(&playlists).Error
func (st *Store) CreatePlaylist(show string, playlist Playlist) (*Playlist, error) {
if _, err := st.CreateShow(show); err != nil {
return nil, err
playlist.ShowName = show
err := st.db.Create(&playlist).Error
return &playlist, err
func (st *Store) GetPlaylist(show string, id uint64) (playlist *Playlist, err error) {
// we have to make sure that the playlist actually belongs to <show> since permissions are enforced
// based on show membership
err = st.db.Where("show_name = ?", show).Preload("Entries", func(db *gorm.DB) *gorm.DB {
return db.Order("playlist_entries.line_num ASC")
}).Preload("Entries.File").First(playlist, id).Error
func (st *Store) UpdatePlaylist(show string, id uint64, playlist Playlist) (out *Playlist, err error) {
defer func() {
if r := recover(); r != nil {
tx.Rollback()
if err == nil {
err = fmt.Errorf("runtime panic: %+v", r)
}
if err = tx.Error; err != nil {
return
// make sure the file exists and actually belongs to <show> since permissions are enforced
// based on show membership
if err = tx.Where("show_name = ?", show).First(&Playlist{}, id).Error; err != nil {
if err = tx.Delete(&PlaylistEntry{}, "playlist_id = ?", id).Error; err != nil {
}
playlist.ID = id
playlist.ShowName = show
if err = tx.Save(&playlist).Error; err != nil {
err = tx.Commit().Error
out = &playlist
return
func (st *Store) DeletePlaylist(show string, id uint64) (err error) {
// we have to make sure that the playlist actually belongs to <show> since permissions are enforced
// based on show membership
result := st.db.Where("show_name = ?", show).Delete(&Playlist{ID: id})
if result.RowsAffected == 0 {
return ErrNotFound