123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- package main
- import (
- "flag"
- "fmt"
- "net"
- "os"
- "os/signal"
- "time"
- "git.lattuga.net/boyska/direttoforo"
- "git.lattuga.net/boyska/direttoforo/liquidsoap"
- "git.lattuga.net/boyska/direttoforo/uiserver"
- )
- func main() {
- liqfile := flag.String("liq", "foo.liq", "Path to liquidsoap script to run")
- bindpath := flag.String("bindpath", "/var/lib/direttoforo/ui.sock", "UNIX domain socket path for UIs")
- flag.Parse()
- state := direttoforo.NewState()
- netUIsock, err := net.Listen("unix", *bindpath)
- if err != nil {
- fmt.Fprintln(os.Stderr, "error binding UI socket!")
- fmt.Fprintln(os.Stderr, err)
- os.Exit(1)
- return
- }
- netUI := uiserver.NewNetUI(&state)
- go func() {
- err := netUI.Run(netUIsock)
- if err != nil {
- fmt.Fprintln(os.Stderr, "NetUI error", err)
- }
- }()
- killLs := make(chan struct{}) // when it is closed, liquidsoap will die
- killed := make(chan os.Signal, 1)
- signal.Notify(killed, os.Interrupt) // ctrl-c
- output, exit, err := liquidsoap.RunLiquidsoap(*liqfile, killLs)
- if err != nil {
- fmt.Fprintln(os.Stderr, "Error spawning liquidsoap", err)
- os.Exit(1)
- }
- go func(log <-chan liquidsoap.Output) {
- for {
- msg := <-log
- if msg.Msg != "" && msg.Level < 3 {
- fmt.Println("msg", msg)
- }
- }
- }(output)
- go func() {
- tick := time.Tick(3 * time.Second)
- for {
- <-tick
- t, err := liquidsoap.NewTelnet("localhost", 1234)
- if err != nil {
- fmt.Println("telnet connection errored", err)
- continue
- }
- t.Conn.SetDeadline(time.Now().Add(3 * time.Second))
- outs, err := t.Outputs()
- if err != nil {
- if err.Error() != "EOF" {
- fmt.Println("telnet cmd errored", err)
- }
- continue
- }
- changed := false
- for name, newstream := range outs {
- if stream, exists := state.Streams[name]; exists {
- if newstream != stream {
- state.Streams[name] = newstream
- changed = true
- }
- } else {
- state.Streams[name] = newstream
- changed = true
- }
- }
- t.Close()
- if changed {
- fmt.Println("state=", state)
- netUI.Update()
- }
- }
- }()
- for {
- select {
- case how := <-exit: // liquidsoap exits
- if !how.Success() {
- fmt.Fprintln(os.Stderr, "liquidsoap terminated,", how.Err)
- netUI.Close()
- os.Exit(1)
- }
- os.Exit(0)
- case <-killed: // we receive a SIGINT: ask liquidsoap to die is enough
- netUI.Close()
- close(killLs)
- fmt.Println("Closed by user interaction, waiting for liquidsoap to exit")
- // TODO: schedule a more aggressive SIGKILL if liquidsoap doesn't
- // exit soon
- }
- }
- }
|