From 799a263baf799a5c20b8c76d9d124004b913f765 Mon Sep 17 00:00:00 2001
From: ale <ale@incal.net>
Date: Wed, 21 Oct 2015 15:50:58 +0000
Subject: [PATCH] move some code around to make it public

---
 api.go                   |  7 ++++
 cmd/radioctl/radioctl.go |  7 +---
 debug.go                 | 73 ++++++++++++++++++++++++++++++++++++++++
 fe/http.go               | 65 ++---------------------------------
 4 files changed, 83 insertions(+), 69 deletions(-)
 create mode 100644 debug.go

diff --git a/api.go b/api.go
index 68b8596a..57372bdc 100644
--- a/api.go
+++ b/api.go
@@ -7,6 +7,7 @@ import (
 	"encoding/json"
 	"errors"
 	"fmt"
+	"hash/crc32"
 	"net"
 	"strings"
 	"time"
@@ -403,3 +404,9 @@ func GeneratePassword() string {
 	rand.Read(b)
 	return base64.StdEncoding.EncodeToString(b)
 }
+
+// GenerateUsername returns a username somehow related to the name of
+// the mount, possibly unique (but not actually guaranteed to be so).
+func GenerateUsername(path string) string {
+	return fmt.Sprintf("source%d", crc32.ChecksumIEEE([]byte(path)))
+}
diff --git a/cmd/radioctl/radioctl.go b/cmd/radioctl/radioctl.go
index a30a16d3..2ec35a82 100644
--- a/cmd/radioctl/radioctl.go
+++ b/cmd/radioctl/radioctl.go
@@ -4,7 +4,6 @@ import (
 	"encoding/json"
 	"flag"
 	"fmt"
-	"hash/crc32"
 	"log"
 	"net/url"
 	"os"
@@ -140,14 +139,10 @@ func getClient() *autoradio.Client {
 	return autoradio.NewClient(autoradio.NewEtcdClient(false))
 }
 
-func generateUsername(path string) string {
-	return fmt.Sprintf("source%d", crc32.ChecksumIEEE([]byte(path)))
-}
-
 func setRelay(m *autoradio.Mount, relayUrl string) {
 	if relayUrl == "" {
 		// Randomly generate source credentials.
-		m.Username = generateUsername(m.Name)
+		m.Username = autoradio.GenerateUsername(m.Name)
 		m.Password = autoradio.GeneratePassword()
 	} else {
 		// Validate the given relay URL.
diff --git a/debug.go b/debug.go
new file mode 100644
index 00000000..13fe66df
--- /dev/null
+++ b/debug.go
@@ -0,0 +1,73 @@
+package autoradio
+
+import "sort"
+
+// MountStatus reports the configuration and status of a mount,
+// including eventual transcoded mounts that source it.
+type MountStatus struct {
+	Mount       *Mount
+	Listeners   int
+	TransMounts []*MountStatus
+}
+
+func newMountStatus(m *Mount, nodes []*NodeStatus) *MountStatus {
+	var listeners int
+	for _, n := range nodes {
+		for _, ims := range n.Mounts {
+			if ims.Name == m.Name {
+				listeners += ims.Listeners
+				break
+			}
+		}
+	}
+	return &MountStatus{
+		Mount:     m,
+		Listeners: listeners,
+	}
+}
+
+type mountStatusList []*MountStatus
+
+func (l mountStatusList) Len() int      { return len(l) }
+func (l mountStatusList) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
+func (l mountStatusList) Less(i, j int) bool {
+	return l[i].Mount.Name < l[j].Mount.Name
+}
+
+// MountsToStatus converts a list of mounts (and eventually the
+// current list of nodes) to a nicely sorted and tree-aggregated list
+// of MountStatus objects. The list of nodes can be nil, in which case
+// listener statistics will be omitted.
+func MountsToStatus(mounts []*Mount, nodes []*NodeStatus) []*MountStatus {
+	// Aggregate stats, and create a tree of transcoding mounts.
+	ms := make(map[string]*MountStatus)
+	for _, m := range mounts {
+		if m.HasTranscoder() {
+			continue
+		}
+		ms[m.Name] = newMountStatus(m, nodes)
+	}
+	for _, m := range mounts {
+		if !m.HasTranscoder() {
+			continue
+		}
+		src := ms[m.Transcoding.SourceName]
+		if src == nil {
+			continue
+		}
+		src.TransMounts = append(src.TransMounts, newMountStatus(m, nodes))
+	}
+	msl := make([]*MountStatus, 0, len(ms))
+	for _, m := range ms {
+		msl = append(msl, m)
+	}
+
+	// Sort everything (including transcoded mounts).
+	sort.Sort(mountStatusList(msl))
+	for _, s := range msl {
+		if s.TransMounts != nil {
+			sort.Sort(mountStatusList(s.TransMounts))
+		}
+	}
+	return msl
+}
diff --git a/fe/http.go b/fe/http.go
index 596f1482..a37a4fe9 100644
--- a/fe/http.go
+++ b/fe/http.go
@@ -11,7 +11,6 @@ import (
 	"net/http"
 	"net/url"
 	"path/filepath"
-	"sort"
 	"strconv"
 	"strings"
 	"time"
@@ -266,76 +265,16 @@ func (h *HTTPRedirector) serveSource(mount *autoradio.Mount, w http.ResponseWrit
 	proxy.ServeHTTP(w, r)
 }
 
-type mountStatus struct {
-	Mount       *autoradio.Mount
-	Listeners   int
-	TransMounts []*mountStatus
-}
-
-func newMountStatus(m *autoradio.Mount, nodes []*autoradio.NodeStatus) *mountStatus {
-	var listeners int
-	for _, n := range nodes {
-		for _, ims := range n.Mounts {
-			if ims.Name == m.Name {
-				listeners += ims.Listeners
-				break
-			}
-		}
-	}
-	return &mountStatus{
-		Mount:     m,
-		Listeners: listeners,
-	}
-}
-
-type mountStatusList []*mountStatus
-
-func (l mountStatusList) Len() int      { return len(l) }
-func (l mountStatusList) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
-func (l mountStatusList) Less(i, j int) bool {
-	return l[i].Mount.Name < l[j].Mount.Name
-}
-
 // Serve our cluster status page.
 func (h *HTTPRedirector) serveStatusPage(w http.ResponseWriter, r *http.Request) {
 	nodes, _ := h.client.GetNodes()
 	mounts, _ := h.client.ListMounts()
 
-	// Aggregate stats, and create a tree of transcoding mounts.
-	ms := make(map[string]*mountStatus)
-	for _, m := range mounts {
-		if m.HasTranscoder() {
-			continue
-		}
-		ms[m.Name] = newMountStatus(m, nodes)
-	}
-	for _, m := range mounts {
-		if !m.HasTranscoder() {
-			continue
-		}
-		src := ms[m.Transcoding.SourceName]
-		if src == nil {
-			continue
-		}
-		src.TransMounts = append(src.TransMounts, newMountStatus(m, nodes))
-	}
-	msl := make([]*mountStatus, 0, len(ms))
-	for _, m := range ms {
-		msl = append(msl, m)
-	}
-
-	// Sort everything.
-	sort.Sort(mountStatusList(msl))
-	for _, s := range msl {
-		if s.TransMounts != nil {
-			sort.Sort(mountStatusList(s.TransMounts))
-		}
-	}
-
+	msl := autoradio.MountsToStatus(mounts, nodes)
 	ctx := struct {
 		Domain string
 		Nodes  []*autoradio.NodeStatus
-		Mounts []*mountStatus
+		Mounts []*autoradio.MountStatus
 	}{h.domain, nodes, msl}
 
 	var buf bytes.Buffer
-- 
GitLab