|
@@ -0,0 +1,104 @@
|
|
|
+package liquidsoap
|
|
|
+
|
|
|
+import (
|
|
|
+ "bufio"
|
|
|
+ "fmt"
|
|
|
+ "net"
|
|
|
+ "strings"
|
|
|
+)
|
|
|
+
|
|
|
+// Client represents a telnet/unix domain connection to Liquidsoap
|
|
|
+//
|
|
|
+// A Client can perform low-level operations, such as Command(), or high-level operations such as Outputs()
|
|
|
+type Client struct {
|
|
|
+ Conn net.Conn
|
|
|
+}
|
|
|
+
|
|
|
+// NewTelnet returns a liquidsoap.Client created using telnet on the given parameters
|
|
|
+func NewTelnet(host string, port int) (Client, error) {
|
|
|
+ conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", host, port))
|
|
|
+ if err != nil {
|
|
|
+ return Client{}, err
|
|
|
+ }
|
|
|
+ return Client{Conn: conn}, nil
|
|
|
+}
|
|
|
+
|
|
|
+// Close closes the connection
|
|
|
+func (c *Client) Close() {
|
|
|
+ if c.Conn != nil {
|
|
|
+ c.Conn.Write([]byte("quit\n"))
|
|
|
+ c.Conn.Close()
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// Command run a command, wait for output response to come and returns it
|
|
|
+func (c *Client) Command(cmdline string) (string, error) {
|
|
|
+ c.Conn.Write([]byte(cmdline + "\n"))
|
|
|
+ var out, line string
|
|
|
+ var err error
|
|
|
+ reader := bufio.NewReader(c.Conn)
|
|
|
+ for {
|
|
|
+ if line, err = reader.ReadString('\n'); err != nil {
|
|
|
+ return "", err
|
|
|
+ }
|
|
|
+ line = line[:len(line)-2] + "\n" // \r\n -> \n
|
|
|
+ if line == "END\n" {
|
|
|
+ return out, nil
|
|
|
+ }
|
|
|
+ out += line
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// Outputs will return a map of outputs that liquidsoap is handling.
|
|
|
+// An output is set to true if it is enabled
|
|
|
+func (c *Client) Outputs() (outputs map[string]bool, err error) {
|
|
|
+ outputs = make(map[string]bool)
|
|
|
+ var cmdout string
|
|
|
+ cmdout, err = c.Command("list")
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ lines := strings.Split(cmdout, "\n")
|
|
|
+ for _, l := range lines {
|
|
|
+ parts := strings.SplitN(l, " : ", 2)
|
|
|
+ if len(parts) < 2 {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ if strings.Index(parts[1], "output.") == 0 {
|
|
|
+ name := strings.TrimSpace(parts[0])
|
|
|
+ var enabled bool
|
|
|
+ enabled, err = c.GetOutput(name)
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ outputs[name] = enabled
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// GetOutput checks whether an output is enabled
|
|
|
+func (c *Client) GetOutput(name string) (bool, error) {
|
|
|
+ cmdout, err := c.Command(name + ".status")
|
|
|
+ if err != nil {
|
|
|
+ return false, err
|
|
|
+ }
|
|
|
+ return strings.TrimSpace(cmdout) == "on", nil
|
|
|
+}
|
|
|
+
|
|
|
+// SetOutput enables or disables an output
|
|
|
+func (c *Client) SetOutput(name string, enabled bool) error {
|
|
|
+ action := "stop"
|
|
|
+ if enabled {
|
|
|
+ action = "start"
|
|
|
+ }
|
|
|
+ cmdout, err := c.Command(fmt.Sprintf("%s.%s", name, action))
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ if strings.TrimSpace(cmdout) != "OK" {
|
|
|
+ return fmt.Errorf("Error: liquidsoap replied '%s'", cmdout)
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+}
|