radiodiodio/playlist/playlist.go

223 lines
4.5 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
type Playlist struct {
NAME string
CTRACK config.Track_t
CALBUM config.Album_t
LIST []uint32
MAX int
}
type PrettyPlaylist struct {
NAME string
CTRACK config.Track_t
CALBUM config.Album_t
LIST []config.Track_t
MAX int
}
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;
}
func (p *Playlist) Encode() string {
pp := p.Pretty()
res, _ := json.Marshal(pp)
return string(res)
}
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++ {
p.LIST = append(p.LIST, pp.LIST[i].ID)
}
return p
}
// type PrettyPlaylist struct {
// NAME string
// CTRACK config.Track_t
// CALBUM config.Album_t
// LIST []config.Track_t
// MAX int
// }
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
func (p *Playlist) Pop() error {
if len(p.LIST) == 0 {
return errors.New("Playlist is empty")
}
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]
return nil
}
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")
}
slice_head := p.LIST[:k]
slice_move := p.LIST[k+1:at_index+1]
slice_tail := make([]uint32, len(p.LIST[at_index+1:]))
copy(slice_tail, p.LIST[at_index+1:])
// slice_move = append(slice_move, track_id)
pln("from_index: " + strconv.Itoa(k))
pln("at_index: " + strconv.Itoa(at_index))
pln("------")
pln("slice head: ")
print(slice_head)
pln("slice move: ")
print(slice_move)
pln("** ")
pln("slice tail: ")
print(slice_tail)
pln("...........................")
p.LIST = append(slice_head, append(append(slice_move, track_id), slice_tail...)...)
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
}