Compare commits

...

10 commits

Author SHA1 Message Date
cb655d29f5 Add rate-skip command 2023-10-17 16:56:24 -05:00
b2dd7b321a Add current sticker command 2023-08-27 23:43:48 -05:00
83dc41cb8e Rate current track 2023-08-27 20:07:00 -05:00
f0b04b7c05 find-sticker command 2023-08-27 15:47:46 -05:00
440b927141 PrintAll method 2023-08-27 14:48:09 -05:00
942d419bf6 Find method 2023-08-27 13:52:18 -05:00
16933ce0fa ♻️ Song struct to hold song logic 2023-08-27 13:16:53 -05:00
c845d08293 🚚 Rename module 2023-08-27 12:10:18 -05:00
eae30a85fd 🔎🎶 2023-08-27 10:52:03 -05:00
6d4b8c1ebd Stickers ✴️ 2023-08-27 10:49:37 -05:00
16 changed files with 417 additions and 22 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
mpc-extra

58
cmd/current-rate.go Normal file
View file

@ -0,0 +1,58 @@
/*
Copyright © 2023 NAME HERE <EMAIL ADDRESS>
*/
package cmd
import (
"errors"
"strconv"
"codeberg.org/danjones000/mpc-extra/mpd"
"github.com/spf13/cobra"
)
// rateCmd represents the rate command
var rateCmd = &cobra.Command{
Use: "rate [rating]",
Short: "Rates the current playing song: 0-10",
/*
Long: `A longer description that spans multiple lines and likely contains examples
and usage of using your command. For example:
Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
*/
Args: func(cmd *cobra.Command, args []string) error {
if len(args) < 1 {
return errors.New("Missing rating")
}
num, err := strconv.Atoi(args[0])
if err != nil {
return err
}
if num < 0 || num > 10 {
return errors.New("Rating must be between zero and ten")
}
return nil
},
Run: func(cmd *cobra.Command, args []string) {
curr, _ := mpd.GetCurrent()
curr.AddSticker("rating", args[0])
curr.PrintAll(true)
},
}
func init() {
currentCmd.AddCommand(rateCmd)
// Here you will define your flags and configuration settings.
// Cobra supports Persistent Flags which will work for this command
// and all subcommands, e.g.:
// rateCmd.PersistentFlags().String("foo", "", "A help for foo")
// Cobra supports local flags which will only run when this command
// is called directly, e.g.:
// rateCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}

51
cmd/current-sticker.go Normal file
View file

@ -0,0 +1,51 @@
/*
Copyright © 2023 NAME HERE <EMAIL ADDRESS>
*/
package cmd
import (
"codeberg.org/danjones000/mpc-extra/mpd"
"github.com/spf13/cobra"
)
// stickerCmd represents the sticker command
var currStickerCmd = &cobra.Command{
Use: "sticker name value",
Args: cobra.MinimumNArgs(2),
Short: "Adds a sticker to the current song",
/*
Long: `A longer description that spans multiple lines and likely contains examples
and usage of using your command. For example:
Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
*/
RunE: func(cmd *cobra.Command, args []string) error {
name := args[0]
if name == "rating" {
root := cmd.Root()
root.SetArgs([]string{"current", "rate", "--", args[1]})
root.TraverseChildren = false
return root.Execute()
}
curr, _ := mpd.GetCurrent()
curr.AddSticker(name, args[1])
curr.PrintAll(true)
return nil
},
}
func init() {
currentCmd.AddCommand(currStickerCmd)
// Here you will define your flags and configuration settings.
// Cobra supports Persistent Flags which will work for this command
// and all subcommands, e.g.:
// stickerCmd.PersistentFlags().String("foo", "", "A help for foo")
// Cobra supports local flags which will only run when this command
// is called directly, e.g.:
// stickerCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}

View file

@ -4,28 +4,25 @@ Copyright © 2023 NAME HERE <EMAIL ADDRESS>
package cmd
import (
"fmt"
"codeberg.org/danjones000/mpc-plus/mpd"
"codeberg.org/danjones000/mpc-extra/mpd"
"github.com/spf13/cobra"
)
// currentCmd represents the current command
var currentCmd = &cobra.Command{
Use: "current",
Short: "A brief description of your command",
Long: `A longer description that spans multiple lines and likely contains examples
and usage of using your command. For example:
Short: "Shows information about the currently playing song",
/*
Long: `A longer description that spans multiple lines and likely contains examples
and usage of using your command. For example:
Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
*/
Run: func(cmd *cobra.Command, args []string) {
conn, _ := mpd.GetConn()
curr, _ := conn.CurrentSong()
for k, v := range curr {
fmt.Println(k, ":", v)
}
curr, _ := mpd.GetCurrent()
curr.PrintAll(true)
},
}

47
cmd/find-sticker.go Normal file
View file

@ -0,0 +1,47 @@
/*
Copyright © 2023 NAME HERE <EMAIL ADDRESS>
*/
package cmd
import (
"fmt"
"codeberg.org/danjones000/mpc-extra/mpd"
"github.com/spf13/cobra"
)
// stickerCmd represents the sticker command
var stickerCmd = &cobra.Command{
Use: "sticker [sticker-name]",
Args: cobra.MinimumNArgs(1),
Short: "A brief description of your command",
/*
Long: `A longer description that spans multiple lines and likely contains examples
and usage of using your command. For example:
Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
*/
Run: func(cmd *cobra.Command, args []string) {
name := args[0]
songs, _ := mpd.StickerFind(name)
for _, song := range songs {
fmt.Println(song.Path, name, ":", song.GetSticker(name))
}
},
}
func init() {
findCmd.AddCommand(stickerCmd)
// Here you will define your flags and configuration settings.
// Cobra supports Persistent Flags which will work for this command
// and all subcommands, e.g.:
// stickerCmd.PersistentFlags().String("foo", "", "A help for foo")
// Cobra supports local flags which will only run when this command
// is called directly, e.g.:
// stickerCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}

47
cmd/find.go Normal file
View file

@ -0,0 +1,47 @@
/*
Copyright © 2023 NAME HERE <EMAIL ADDRESS>
*/
package cmd
import (
"fmt"
"codeberg.org/danjones000/mpc-extra/mpd"
"github.com/spf13/cobra"
)
// findCmd represents the find command
var findCmd = &cobra.Command{
Use: "find",
Short: "A brief description of your command",
/*
Long: `A longer description that spans multiple lines and likely contains examples
and usage of using your command. For example:
Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
*/
Run: func(cmd *cobra.Command, args []string) {
ret, _ := mpd.Find(args...)
for _, song := range ret {
song.PrintAll(false)
fmt.Println("-------")
}
},
}
func init() {
rootCmd.AddCommand(findCmd)
// Here you will define your flags and configuration settings.
// Cobra supports Persistent Flags which will work for this command
// and all subcommands, e.g.:
// findCmd.PersistentFlags().String("foo", "", "A help for foo")
// Cobra supports local flags which will only run when this command
// is called directly, e.g.:
// findCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}

31
cmd/rate-skip.go Normal file
View file

@ -0,0 +1,31 @@
/*
Copyright © 2023 Dan Jones
*/
package cmd
import (
"codeberg.org/danjones000/mpc-extra/mpd"
"github.com/spf13/cobra"
)
// rateSkipCmd represents the rate-skip command
var rateSkipCmd = &cobra.Command{
Use: "rate-skip [rating]",
Args: cobra.MinimumNArgs(1),
Short: "Rate the current song, and skip to the next",
RunE: func(cmd *cobra.Command, args []string) error {
root := cmd.Root()
root.SetArgs([]string{"current", "rate", "--", args[0]})
root.TraverseChildren = false
err := root.Execute()
if err != nil {
return err
}
return mpd.Next()
},
}
func init() {
rootCmd.AddCommand(rateSkipCmd)
}

View file

@ -14,7 +14,7 @@ import (
// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "mpc-plus",
Use: "mpc-extra",
Short: "A brief description of your application",
Long: `A longer description that spans multiple lines and likely contains
examples and usage of using your application. For example:
@ -41,7 +41,7 @@ func init() {
// Cobra supports persistent flags, which, if defined here,
// will be global for your application.
// rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.mpc-plus.yaml)")
// rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.mpc-extra.yaml)")
// Cobra also supports local flags, which will only run
// when this action is called directly.

3
go.mod
View file

@ -1,8 +1,9 @@
module codeberg.org/danjones000/mpc-plus
module codeberg.org/danjones000/mpc-extra
go 1.20
require (
github.com/akrennmair/slice v0.0.0-20220105203817-49445747ab81
github.com/fhs/gompd/v2 v2.3.0
github.com/spf13/cobra v1.7.0
)

6
go.sum
View file

@ -1,12 +1,18 @@
github.com/akrennmair/slice v0.0.0-20220105203817-49445747ab81 h1:HnuAxArB0uUxqjRvZdjhBxE3uPXNeJvNNbuaV4QhHMU=
github.com/akrennmair/slice v0.0.0-20220105203817-49445747ab81/go.mod h1:jk5mJ+KFznfxbCEsOPgmJkozvBfVGeaqIMs31NhXlv0=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/fhs/gompd/v2 v2.3.0 h1:wuruUjmOODRlJhrYx73rJnzS7vTSXSU7pWmZtM3VPE0=
github.com/fhs/gompd/v2 v2.3.0/go.mod h1:nNdZtcpD5VpmzZbRl5rV6RhxeMmAWTxEsSIMBkmMIy4=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View file

@ -4,8 +4,8 @@ Copyright © 2023 NAME HERE <EMAIL ADDRESS>
package main
import (
"codeberg.org/danjones000/mpc-plus/cmd"
"codeberg.org/danjones000/mpc-plus/mpd"
"codeberg.org/danjones000/mpc-extra/cmd"
"codeberg.org/danjones000/mpc-extra/mpd"
)
func main() {

View file

@ -1,8 +1,6 @@
package mpd
import (
"github.com/fhs/gompd/v2/mpd"
)
import "github.com/fhs/gompd/v2/mpd"
var conn *mpd.Client
var connerror error
@ -22,3 +20,17 @@ func CloseConn() error {
}
return conn.Close()
}
func Next() error {
if connerror != nil {
return connerror
}
return conn.Next()
}
func Previous() error {
if connerror != nil {
return connerror
}
return conn.Previous()
}

13
mpd/current.go Normal file
View file

@ -0,0 +1,13 @@
package mpd
func GetCurrent() (*Song, error) {
if connerror != nil {
return nil, connerror
}
curr, err := conn.CurrentSong()
if err != nil {
return nil, err
}
return newSong(curr), nil
}

16
mpd/find.go Normal file
View file

@ -0,0 +1,16 @@
package mpd
import "github.com/akrennmair/slice"
func Find(args ...string) ([]*Song, error) {
if connerror != nil {
return nil, connerror
}
songs, err := conn.Search(args...)
if err != nil {
return nil, err
}
return slice.Map(songs, newSong), nil
}

85
mpd/song.go Normal file
View file

@ -0,0 +1,85 @@
package mpd
import (
"fmt"
"github.com/akrennmair/slice"
"github.com/fhs/gompd/v2/mpd"
)
type Song struct {
Path string
Attrs mpd.Attrs
stickers []mpd.Sticker
// @todo refactor as a map so there's no dupes
}
func newSong(attrs mpd.Attrs) *Song {
return &Song{
Path: attrs["file"],
Attrs: attrs,
}
}
func (s *Song) GetStickers() ([]mpd.Sticker, error) {
if s.stickers != nil {
return s.stickers, nil
}
if connerror != nil {
return nil, connerror
}
sticks, err := StickersGetFor(s.Path)
s.stickers = sticks
return s.stickers, err
}
func (s *Song) PrintAll(withStickers bool) {
for k, v := range s.Attrs {
fmt.Println(k, ":", v)
}
if withStickers {
sticks, _ := s.GetStickers()
for _, v := range sticks {
fmt.Println(v.Name, "*:", v.Value)
}
}
}
func (s *Song) GetSticker(name string) string {
if s.stickers != nil {
ret := slice.Filter(s.stickers, func(sticker mpd.Sticker) bool {
return sticker.Name == name
})
if ret != nil && len(ret) > 0 {
last := ret[len(ret)-1]
return last.Value
}
}
if connerror != nil {
return ""
}
found, err := conn.StickerGet(s.Path, name)
if err != nil {
return ""
}
s.stickers = append(s.stickers, *found)
return found.Value
}
func (s *Song) AddSticker(name, value string) error {
ret := conn.StickerSet(s.Path, name, value)
if ret == nil {
if s.stickers == nil || len(s.stickers) == 0 {
s.GetStickers()
} else {
s.stickers = append(s.stickers, mpd.Sticker{Name: name, Value: value})
}
}
return ret
}

30
mpd/stickers.go Normal file
View file

@ -0,0 +1,30 @@
package mpd
import "github.com/fhs/gompd/v2/mpd"
func StickersGetFor(file string) ([]mpd.Sticker, error) {
if connerror != nil {
return nil, connerror
}
return conn.StickerList(file)
}
func StickerFind(name string) ([]*Song, error) {
if connerror != nil {
return nil, connerror
}
paths, sticks, err := conn.StickerFind("", name)
if err != nil {
return nil, err
}
ret := make([]*Song, len(paths))
for i := 0; i < len(paths); i++ {
ret[i] = newSong(mpd.Attrs{"file": paths[i]})
ret[i].stickers = []mpd.Sticker{sticks[i]}
}
return ret, nil
}