Skip to content
Snippets Groups Projects
types.go 4.7 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 (
    	"errors"
    
    Christian Pointner's avatar
    Christian Pointner committed
    	"time"
    
    
    	"github.com/jinzhu/gorm"
    
    	FileURIScheme = "file"
    
    
    	// well-known table names
    
    	migrationsTn = "__migrations__"
    
    Christian Pointner's avatar
    Christian Pointner committed
    
    	// fixtures
    	publicGroupName = "public"
    
    //******* Errors
    
    // TODO: make all errors types???
    
    
    Christian Pointner's avatar
    Christian Pointner committed
    var (
    
    Christian Pointner's avatar
    Christian Pointner committed
    	ErrNotImplemented = errors.New("not implemented")
    	ErrNotFound       = gorm.ErrRecordNotFound
    
    type ErrFileInUse struct {
    	Playlists Playlists `json:"playlists"`
    }
    
    func (e *ErrFileInUse) Error() string {
    
    	return fmt.Sprintf("the file is still in use by %d playlist(s)", len(e.Playlists))
    
    //******* Groups
    
    type Group struct {
    
    	Name      string    `json:"name" gorm:"primary_key"`
    	CreatedAt time.Time `json:"created"`
    	UpdatedAt time.Time `json:"updated"`
    
    }
    
    func (g Group) String() string {
    	return g.Name
    }
    
    
    Christian Pointner's avatar
    Christian Pointner committed
    type Groups []Group
    
    
    //******* Files
    
    
    type ImportState int
    
    const (
    	ImportNew ImportState = iota
    	ImportPending
    	ImportRunning
    	ImportDone
    	ImportAborted
    )
    
    func (s ImportState) String() string {
    	switch s {
    	case ImportNew:
    		return "new"
    	case ImportPending:
    		return "pending"
    	case ImportRunning:
    		return "running"
    	case ImportDone:
    		return "done"
    	case ImportAborted:
    		return "aborted"
    	}
    	return "unknown"
    }
    
    func (s *ImportState) fromString(str string) error {
    	switch str {
    	case "new":
    		*s = ImportNew
    	case "pending":
    		*s = ImportPending
    	case "running":
    		*s = ImportRunning
    	case "done":
    		*s = ImportDone
    	case "aborted":
    		*s = ImportAborted
    	default:
    		return errors.New("invalid import state: '" + str + "'")
    	}
    	return nil
    }
    
    func (s ImportState) MarshalText() (data []byte, err error) {
    	data = []byte(s.String())
    	return
    }
    
    func (s *ImportState) UnmarshalText(data []byte) (err error) {
    	return s.fromString(string(data))
    }
    
    
    // type ImportLogLine struct {
    // 	Timestamp time.Time `json:"timestamp"`
    // 	Message   string    `json:"message"`
    // }
    
    // type ImportLog []ImportLogLine
    
    // func (l ImportLog) Append(message string) {
    // 	l = append(l, ImportLogLine{time.Now(), message})
    // }
    
    
    type Import struct {
    
    	State   ImportState `json:"state"`
    	Success bool        `json:"success"`
    
    	//	Log     ImportLog   `json:"log"`
    }
    
    Christian Pointner's avatar
    Christian Pointner committed
    type FileSource struct {
    
    	URI    string `json:"uri"`
    	Hash   string `json:"hash"`
    	Import Import `json:"import" gorm:"embedded;embedded_prefix:import__"`
    
    Christian Pointner's avatar
    Christian Pointner committed
    }
    
    type FileMetadata struct {
    
    	// TODO: actually a full-text index would be nice here...
    
    	Artist string `json:"artist,omitempty" gorm:"index"`
    	Title  string `json:"title,omitempty" gorm:"index"`
    	Album  string `json:"album,omitempty" gorm:"index"`
    
    Christian Pointner's avatar
    Christian Pointner committed
    	// TODO: add more fields
    }
    
    type File struct {
    
    	ID        uint64        `json:"id" gorm:"primary_key"`
    	CreatedAt time.Time     `json:"created"`
    	UpdatedAt time.Time     `json:"updated"`
    	GroupName string        `json:"group" gorm:"not null;index"`
    	Group     Group         `json:"-" gorm:"association_foreignkey:Name"`
    	Source    FileSource    `json:"source" gorm:"embedded;embedded_prefix:source__"`
    	Metadata  FileMetadata  `json:"metadata" gorm:"embedded;embedded_prefix:metadata__"`
    	Size      uint64        `json:"size"`
    	Duration  time.Duration `json:"duration"`
    
    //******* Playlists
    
    type PlaylistEntry struct {
    
    	ID         uint64  `json:"-" gorm:"primary_key"`
    
    	PlaylistID uint64  `json:"-" gorm:"not null;index;unique_index:unique_playlist_line_numbers"`
    	LineNum    uint    `json:"-" gorm:"not null;unique_index:unique_playlist_line_numbers"`
    
    	URI        string  `json:"uri"`
    
    	File       *File   `json:"file,omitempty" gorm:"association_autoupdate:false;association_autocreate:false"`
    
    	FileID     *uint64 `json:"-" gorm:"index"`
    
    type Playlist struct {
    
    	ID        uint64          `json:"id" gorm:"primary_key"`
    	CreatedAt time.Time       `json:"created"`
    	UpdatedAt time.Time       `json:"updated"`
    	GroupName string          `json:"group" gorm:"not null;index"`
    	Group     Group           `json:"-" gorm:"association_foreignkey:Name"`
    
    	Entries   []PlaylistEntry `json:"entries,omitempty"`
    
    type Playlists []Playlist
    
    
    //****************