feat: v6 rewrite
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/Ullaakut/cameradar/v6"
|
||||
)
|
||||
|
||||
// FormatSummary builds a human-readable summary of discovered streams.
|
||||
func FormatSummary(streams []cameradar.Stream, _ error) string {
|
||||
accessible, others := partitionStreams(streams)
|
||||
|
||||
var builder strings.Builder
|
||||
builder.WriteString(fmt.Sprintf("Accessible streams: %d\n", len(accessible)))
|
||||
if len(accessible) == 0 {
|
||||
builder.WriteString("• None\n")
|
||||
} else {
|
||||
for _, stream := range accessible {
|
||||
builder.WriteString(formatStream(stream))
|
||||
}
|
||||
}
|
||||
|
||||
if len(others) > 0 {
|
||||
builder.WriteString("\n")
|
||||
builder.WriteString(fmt.Sprintf("Other discovered streams: %d\n", len(others)))
|
||||
for _, stream := range others {
|
||||
builder.WriteString(formatStream(stream))
|
||||
}
|
||||
}
|
||||
|
||||
return builder.String()
|
||||
}
|
||||
|
||||
func partitionStreams(streams []cameradar.Stream) ([]cameradar.Stream, []cameradar.Stream) {
|
||||
var accessible []cameradar.Stream
|
||||
var others []cameradar.Stream
|
||||
for _, stream := range streams {
|
||||
if stream.Available {
|
||||
accessible = append(accessible, stream)
|
||||
} else {
|
||||
others = append(others, stream)
|
||||
}
|
||||
}
|
||||
|
||||
// Sort streams by address and port.
|
||||
sort.Slice(accessible, func(i, j int) bool {
|
||||
if accessible[i].Address.String() == accessible[j].Address.String() {
|
||||
return accessible[i].Port < accessible[j].Port
|
||||
}
|
||||
return accessible[i].Address.String() < accessible[j].Address.String()
|
||||
})
|
||||
sort.Slice(others, func(i, j int) bool {
|
||||
if others[i].Address.String() == others[j].Address.String() {
|
||||
return others[i].Port < others[j].Port
|
||||
}
|
||||
return others[i].Address.String() < others[j].Address.String()
|
||||
})
|
||||
|
||||
return accessible, others
|
||||
}
|
||||
|
||||
func formatStream(stream cameradar.Stream) string {
|
||||
var builder strings.Builder
|
||||
builder.WriteString("• ")
|
||||
builder.WriteString(stream.Address.String())
|
||||
builder.WriteString(":")
|
||||
builder.WriteString(strconv.FormatUint(uint64(stream.Port), 10))
|
||||
|
||||
if stream.Device != "" {
|
||||
builder.WriteString(" (")
|
||||
builder.WriteString(stream.Device)
|
||||
builder.WriteString(")")
|
||||
}
|
||||
builder.WriteString("\n")
|
||||
|
||||
builder.WriteString(" Authentication: ")
|
||||
builder.WriteString(authTypeLabel(stream.AuthenticationType))
|
||||
builder.WriteString("\n")
|
||||
|
||||
if len(stream.Routes) > 0 {
|
||||
builder.WriteString(" Routes: ")
|
||||
builder.WriteString(strings.Join(stream.Routes, ", "))
|
||||
builder.WriteString("\n")
|
||||
} else {
|
||||
builder.WriteString(" Routes: not found\n")
|
||||
}
|
||||
|
||||
if stream.CredentialsFound {
|
||||
builder.WriteString(" Credentials: ")
|
||||
builder.WriteString(stream.Username)
|
||||
builder.WriteString(":")
|
||||
builder.WriteString(stream.Password)
|
||||
builder.WriteString("\n")
|
||||
} else {
|
||||
builder.WriteString(" Credentials: not found\n")
|
||||
}
|
||||
|
||||
builder.WriteString(" Availability: ")
|
||||
if stream.Available {
|
||||
builder.WriteString("yes\n")
|
||||
} else {
|
||||
builder.WriteString("no\n")
|
||||
}
|
||||
|
||||
if stream.RouteFound && stream.CredentialsFound {
|
||||
builder.WriteString(" RTSP URL: ")
|
||||
builder.WriteString(formatRTSPURL(stream))
|
||||
builder.WriteString("\n")
|
||||
}
|
||||
|
||||
builder.WriteString(" Admin panel: ")
|
||||
builder.WriteString(formatAdminPanelURL(stream))
|
||||
builder.WriteString("\n")
|
||||
|
||||
return builder.String()
|
||||
}
|
||||
|
||||
func formatRTSPURL(stream cameradar.Stream) string {
|
||||
path := stream.Route()
|
||||
if path != "" && !strings.HasPrefix(path, "/") {
|
||||
path = "/" + path
|
||||
}
|
||||
|
||||
credentials := ""
|
||||
if stream.Username != "" || stream.Password != "" {
|
||||
credentials = stream.Username + ":" + stream.Password + "@"
|
||||
}
|
||||
|
||||
return fmt.Sprintf("rtsp://%s%s:%d%s", credentials, stream.Address.String(), stream.Port, path)
|
||||
}
|
||||
|
||||
func formatAdminPanelURL(stream cameradar.Stream) string {
|
||||
return fmt.Sprintf("http://%s/", stream.Address.String())
|
||||
}
|
||||
|
||||
func authTypeLabel(auth cameradar.AuthType) string {
|
||||
switch auth {
|
||||
case cameradar.AuthNone:
|
||||
return "none"
|
||||
case cameradar.AuthBasic:
|
||||
return "basic"
|
||||
case cameradar.AuthDigest:
|
||||
return "digest"
|
||||
default:
|
||||
return fmt.Sprintf("unknown(%d)", auth)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user