radiodiodio/playlist/playlist.go

263 lines
5.8 KiB
Go
Raw Normal View History

2019-01-02 16:11:22 +01:00
package playlist
import (
2019-01-02 19:06:45 +01:00
"log"
2019-01-02 16:11:22 +01:00
"time"
"errors"
"strconv"
"math/rand"
"encoding/json"
"../archive"
"../config"
)
2019-01-02 19:06:45 +01:00
var pln = log.Println
2019-01-02 16:11:22 +01:00
2019-01-03 14:21:24 +01:00
type Pop func(*Playlist)
2019-01-02 16:11:22 +01:00
type Playlist struct {
NAME string
CTRACK config.Track_t
CALBUM config.Album_t
LIST []uint32
MAX int
2019-01-03 14:21:24 +01:00
CALLB Pop
2019-01-02 16:11:22 +01:00
}
type PrettyPlaylist struct {
NAME string
CTRACK config.Track_t
CALBUM config.Album_t
LIST []config.Track_t
MAX int
}
2019-01-03 14:21:24 +01:00
type MinimalTrack struct {
ID string `json:"id"`
NAME string `json:"name"`
MAKER string `json:"maker"`
ALBUM string `json:"album"`
}
type MinimalPlaylist struct {
NAME string `json:"name"`
CTRACK string `json:"ctrack"`
CALBUM string `json:"calbum"`
LIST []MinimalTrack `json:"list"`
}
2019-01-02 16:11:22 +01:00
func MakeRandom(name string, max int) (*Playlist, error) {
err := archive.Build()
if err != nil {
return nil, err
}
p := &Playlist{NAME: name, MAX: max}
p.LIST = make([]uint32, max)
for i := 0; i < max; i++ {
r, _ := Random()
p.LIST[i] = r // might duplicate
}
return p, nil;
}
2019-01-04 09:59:01 +01:00
func (mp *MinimalPlaylist) Encode() []byte {
res, err := json.Marshal(mp)
if err != nil {
return nil
}
return res
2019-01-02 16:11:22 +01:00
}
func Decode(jsonstr string) (*Playlist, error) {
pp := &PrettyPlaylist{}
if err := json.Unmarshal([]byte(jsonstr), pp); err != nil {
return nil, err
}
p := pp.Unpretty()
return p, nil
}
func (p *Playlist) Pretty() *PrettyPlaylist {
pp := &PrettyPlaylist{NAME: p.NAME, CTRACK: p.CTRACK, CALBUM: p.CALBUM, MAX: p.MAX}
pp.LIST = make([]config.Track_t, len(p.LIST))
for i := 0; i < len(p.LIST); i++ {
pp.LIST[i] = archive.Archive_map[p.LIST[i]]
}
return pp
}
func (pp *PrettyPlaylist) Unpretty() *Playlist {
p := &Playlist{NAME: pp.NAME, CTRACK: pp.CTRACK, CALBUM: pp.CALBUM, MAX: pp.MAX}
p.LIST = make([]uint32, len(pp.LIST))
for i := 0; i < len(pp.LIST); i++ {
2019-01-03 14:21:24 +01:00
p.LIST[i] = pp.LIST[i].ID
2019-01-02 16:11:22 +01:00
}
return p
}
2019-01-03 14:21:24 +01:00
func (p *Playlist) Minimal() *MinimalPlaylist {
mp := &MinimalPlaylist{NAME: p.NAME, CTRACK: p.CTRACK.NAME}
mp.CALBUM = p.CALBUM.MAKER + " - " + p.CALBUM.NAME
mp.LIST = make([]MinimalTrack, len(p.LIST))
for i := 0; i < len(p.LIST); i++ {
track := archive.Archive_map[p.LIST[i]]
strid := strconv.FormatUint(uint64(track.ID), 10)
mp.LIST[i] = MinimalTrack{ID: strid, NAME: track.NAME, MAKER: track.MAKER, ALBUM: track.ALBUM}
}
return mp
}
2019-01-02 16:11:22 +01:00
func (pp *PrettyPlaylist) Print() {
pln("Name: " + pp.NAME)
pln("CTRACK: " + pp.CTRACK.NAME)
pln("CALBUM: " + pp.CALBUM.NAME)
pln("Next:")
for i, r := range pp.LIST {
pln(" " + strconv.Itoa(i) + " - " + r.NAME)
}
}
2019-01-02 19:06:45 +01:00
func print(slice []uint32) {
for i, r := range slice {
pln(" " + strconv.Itoa(i) + " - " + archive.Archive_map[r].NAME)
}
}
// https://github.com/golang/go/wiki/SliceTricks
2019-01-02 16:11:22 +01:00
// https://stackoverflow.com/questions/33834742/remove-and-adding-elements-to-array-in-go-lang
2019-01-03 14:21:24 +01:00
func (p *Playlist) Pop() (string, error) {
2019-01-02 16:11:22 +01:00
if len(p.LIST) == 0 {
2019-01-03 14:21:24 +01:00
return "", errors.New("Playlist is empty")
2019-01-02 16:11:22 +01:00
}
t := p.LIST[0]
if len(p.LIST) < 2 {
p.LIST = make([]uint32, 0)
} else {
p.LIST = p.LIST[1:]
}
p.CTRACK = archive.Archive_map[t]
p.CALBUM = config.Xcfg.Archive.ALBUMS[p.CTRACK.AID]
2019-01-03 14:21:24 +01:00
if p.CALLB != nil {
p.CALLB(p)
}
return p.CTRACK.PATH, nil
2019-01-02 16:11:22 +01:00
}
func (p *Playlist) Push(track_id uint32) error {
if len(p.LIST) == p.MAX {
return errors.New("Playlist is full")
}
p.LIST = append(p.LIST, track_id)
return nil
}
func (p *Playlist) PushFront(track_id uint32) error {
if len(p.LIST) == p.MAX {
return errors.New("Playlist is full")
}
p.LIST = append([]uint32{ track_id }, p.LIST...) // don't forget '...''
return nil
}
func (p *Playlist) Insert(track_id uint32, at_index int) error {
if at_index > p.MAX {
return errors.New("Invalid insert index")
}
p.LIST = append(p.LIST, 0)
copy(p.LIST[at_index+1:], p.LIST[at_index:])
p.LIST[at_index] = track_id
if len(p.LIST) > p.MAX {
p.LIST = p.LIST[:p.MAX]
}
return nil
}
2019-01-02 19:06:45 +01:00
func (p *Playlist) index(track_id uint32) int {
2019-01-02 16:11:22 +01:00
k := -1
2019-01-02 19:06:45 +01:00
for i := 0; i < len(p.LIST); i++ {
2019-01-02 16:11:22 +01:00
if p.LIST[i] == track_id { k = i }
}
2019-01-02 19:06:45 +01:00
return k
}
2019-01-02 16:11:22 +01:00
2019-01-02 19:06:45 +01:00
func (p *Playlist) Delete(track_id uint32) error {
k := p.index(track_id);
2019-01-02 16:11:22 +01:00
if k < 0 {
return errors.New("Invalid track ID")
}
p.LIST = append(p.LIST[:k-1], p.LIST[k+1:]...)
return nil
2019-01-02 19:06:45 +01:00
}
2019-01-02 16:11:22 +01:00
2019-01-02 19:06:45 +01:00
func (p *Playlist) Move(track_id uint32, at_index int) error {
if at_index > p.MAX {
return errors.New("Invalid insert index")
}
k := p.index(track_id);
if k < 0 {
return errors.New("Invalid track ID")
}
2019-01-03 14:21:24 +01:00
// pln("k: " + strconv.Itoa(k))
// pln("at_index: " + strconv.Itoa(at_index))
// pln("------")
var slice_head, slice_move, slice_tail []uint32
if k < at_index {
slice_head = make([]uint32, len(p.LIST[:k]))
copy(slice_head, p.LIST[:k])
// slice_head = p.LIST[:k]
slice_move = make([]uint32, len(p.LIST[k+1:at_index+1]))
copy(slice_move, p.LIST[k+1:at_index+1])
// slice_move = p.LIST[k:at_index]
slice_tail = make([]uint32, len(p.LIST[at_index+1:]))
copy(slice_tail, p.LIST[at_index+1:])
p.LIST = append(slice_head, append(append(slice_move, track_id), slice_tail...)...)
} else if k > at_index {
slice_head = make([]uint32, len(p.LIST[:at_index]))
copy(slice_head, p.LIST[:at_index])
// slice_head = p.LIST[:at_index]
slice_move = make([]uint32, len(p.LIST[at_index:k]))
copy(slice_move, p.LIST[at_index:k])
// slice_tail = p.LIST[k+1:]
slice_tail = make([]uint32, len(p.LIST[k+1:]))
copy(slice_tail, p.LIST[k+1:])
p.LIST = append(append(append(slice_head, track_id), slice_move...), slice_tail...)
}
2019-01-02 19:06:45 +01:00
2019-01-03 14:21:24 +01:00
// pln("slice head: ")
// print(slice_head)
// pln("slice move: ")
// print(slice_move)
// pln("** ")
// pln("slice tail: ")
// print(slice_tail)
// pln("...........................")
2019-01-02 19:06:45 +01:00
return nil
2019-01-02 16:11:22 +01:00
}
func Random() (uint32, string) {
rand.Seed(time.Now().UTC().UnixNano())
index := archive.Archive_map_keys[rand.Intn(len(archive.Archive_map_keys) - 1)]
return archive.Archive_map[index].ID, archive.Archive_map[index].NAME
}