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 }