Skip to content
Snippets Groups Projects
playlists.go 3.84 KiB
Newer Older
  • Learn to ignore specific revisions
  • Christian Pointner's avatar
    Christian Pointner committed
    //
    //  tank
    //
    //  Import and Playlist Daemon for autoradio project
    //
    //
    
    //  Copyright (C) 2017-2018 Christian Pointner <equinox@helsinki.at>
    
    Christian Pointner's avatar
    Christian Pointner committed
    //
    //  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"
    
    	"strings"
    
    
    	"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://<group>/<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, GroupName: 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)
    		}
    
    	return nil
    }
    
    func (p *Playlist) AfterFind() error {
    	for idx := range p.Entries {
    		if p.Entries[idx].File != nil {
    			urihost := p.Entries[idx].File.GroupName
    			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(group string) (playlists Playlists, err error) {
    
    	err = st.db.Where("group_name = ?", group).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(group string, playlist Playlist) (*Playlist, error) {
    	if _, err := st.CreateGroup(group); err != nil {
    		return nil, err
    	}
    	playlist.ID = 0
    	playlist.GroupName = group
    	err := st.db.Create(&playlist).Error
    
    	// TODO: the returned playlist object will not contain properly initialized File Objects :(
    
    	return &playlist, err
    }
    
    func (st *Store) GetPlaylist(group string, id uint64) (playlist *Playlist, err error) {
    	playlist = &Playlist{}
    
    	// we have to make sure that the playlist actually belongs to <group> since permissions are enforced
    	// based on group membership
    
    	err = st.db.Where("group_name = ?", group).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(group string, id uint64, playlist Playlist) (*Playlist, error) {
    
    Christian Pointner's avatar
    Christian Pointner committed
    	// TODO: implement this
    
    Christian Pointner's avatar
    Christian Pointner committed
    	return nil, ErrNotImplemented
    
    func (st *Store) DeletePlaylist(group string, id uint64) (err error) {
    
    	// we have to make sure that the playlist actually belongs to <group> since permissions are enforced
    	// based on group membership
    	result := st.db.Where("group_name = ?", group).Delete(&Playlist{ID: id})
    	if err = result.Error; err != nil {
    
    	if result.RowsAffected == 0 {
    		return ErrNotFound