Skip to content
Snippets Groups Projects
Commit 2cd16c55 authored by ale's avatar ale
Browse files

add a XSL template to render icecast status in a parsable format, with code to read it

parent ef357f16
No related branches found
No related tags found
No related merge requests found
<xsl:stylesheet xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" version = "1.0" >
<xsl:template match = "/icestats" >
<config>
<xsl:for-each select="source">
<mount>
<title><xsl:value-of select="@mount" /></title>
<name><xsl:value-of select="name" /></name>
<listeners><xsl:value-of select="listeners" /></listeners>
<bitrate><xsl:value-of select="bitrate" /></bitrate>
<url><xsl:value-of select="url" /></url>
</mount>
</xsl:for-each>
</config>
</xsl:template>
</xsl:stylesheet>
......@@ -63,3 +63,7 @@ override_dh_install:
chmod 0755 $(SVCDIR)/$$f/log/run ; \
done)
# Icecast2 status XSL template.
install -d -m 755 -o root -g root $(DESTDIR)/usr/share/icecast2/web
install -m 644 -o root -g root $(CURDIR)/debian/radioai.xsl \
$(DESTDIR)/usr/share/icecast2/web/radioai.xsl
package node
import (
"encoding/xml"
"io"
"net/http"
"os"
"os/exec"
"time"
)
var (
statusPageUrl = "http://localhost:8000/radioai.xsl"
)
type icecastStatusMount struct {
Title string `xml:"title"`
Name string `xml:"name"`
Url string `xml:"url"`
Listeners int `xml:"listeners"`
BitRate int `xml:"bitrate"`
}
type IcecastStatus struct {
XMLName xml.Name `xml:"config"`
Mounts []icecastStatusMount
}
type IcecastController struct {
PublicIp string
ConfigFile string
InitScript string
config *icecastConfig
status *IcecastStatus
stop chan bool
}
func NewIcecastController(publicIp string) *IcecastController {
......@@ -18,6 +41,7 @@ func NewIcecastController(publicIp string) *IcecastController {
ConfigFile: "/etc/icecast2/icecast.conf",
InitScript: "/etc/init.d/icecast2",
config: newIcecastConfig(publicIp),
stop: make(chan bool, 1),
}
}
......@@ -44,3 +68,43 @@ func (ic *IcecastController) Update(conf *ClusterConfig, isMaster bool, masterAd
return ic.reload()
}
func (ic *IcecastController) statusUpdater() {
t := time.NewTicker(3 * time.Second)
for {
select {
case <-t.C:
if status, err := ic.fetchStatus(); err == nil {
ic.status = status
}
case <-ic.stop:
return
}
}
}
func (ic *IcecastController) fetchStatus() (*IcecastStatus, error) {
resp, err := http.Get(statusPageUrl)
if err != nil {
return nil, err
}
defer resp.Body.Close()
return ic.parseStatusPage(resp.Body)
}
func (ic *IcecastController) parseStatusPage(input io.Reader) (*IcecastStatus, error) {
var status IcecastStatus
if err := xml.NewDecoder(input).Decode(&status); err != nil {
return nil, err
}
return &status, nil
}
func (ic *IcecastController) Run() {
go ic.statusUpdater()
}
func (ic *IcecastController) Stop() {
close(ic.stop)
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment