Browse Source

Added the idea of connections

  I just don't seem to be understanding how to have this work, perhaps
some extra eyes (ones who are more skilled at internet) could help.
Apollo 3 years ago
parent
commit
c3b603831b
5 changed files with 186 additions and 32 deletions
  1. 5 0
      finder.txt
  2. 88 1
      poster.go
  3. 28 0
      templates/connect.html
  4. 4 1
      templates/index.html
  5. 61 30
      webserver.go

+ 5 - 0
finder.txt

@@ -0,0 +1,5 @@
+M-SEARCH * HTTP/1.1
+Host: 239.255.255.250:1900
+Man: "ssdp:discover"
+ST: roku:ecp
+

+ 88 - 1
poster.go

@@ -4,7 +4,11 @@ import (
 	"fmt"
 	"io"
 	"log"
+	"net"
 	"net/http"
+	"os"
+	"strings"
+	"time"
 
 	"github.com/beanzilla/glom"
 	"github.com/beego/x2j"
@@ -19,6 +23,80 @@ func Post(where string) *http.Response {
 	return resp
 }
 
+func ListenToRequests(ln *net.UDPConn, data *string) {
+	done := false
+	for !done {
+		buffer := make([]byte, 1024) // 1k
+		ln.SetReadDeadline(time.Now().Add(3 * time.Second))
+		for !done {
+			b, err := ln.Read(buffer)
+			if b > 0 {
+				str := string(buffer[0:])
+				*data += str
+			}
+			if err != nil {
+				if _, ok := err.(net.Error); !ok {
+					log.Print(err)
+					done = true
+				}
+			}
+		}
+	}
+}
+
+func PostFind() error {
+	file, err := os.ReadFile("finder.txt")
+	if err != nil {
+		return err
+	}
+	addr, err := net.ResolveUDPAddr("udp", "239.255.255.250:1900")
+	if err != nil {
+		return err
+	}
+	conn, err := net.DialUDP("udp", nil, addr)
+	if err != nil {
+		return err
+	}
+	defer conn.Close()
+	conn.Write(file)
+	return nil
+}
+
+func GetFind() []string {
+	var data string
+
+	addr, err := net.ResolveUDPAddr("udp", ":1900")
+	if err != nil {
+		log.Printf("GET Find failed getting port 1900, %v", err)
+		return nil
+	}
+	ln, err := net.ListenUDP("udp", addr)
+	if err != nil {
+		log.Printf("GET Find started listener for 1900, %v", err)
+		return nil
+	}
+
+	go ListenToRequests(ln, &data)
+
+	err = PostFind()
+	if err != nil {
+		log.Printf("POST Find returned %v", err)
+	}
+
+	var list []string
+	data_list := strings.Split(data, "\n")
+	for _, line := range data_list {
+		if strings.Contains(line, "Location") {
+			str := strings.ReplaceAll(strings.ToLower(line), "location: ", "")
+			str = strings.ReplaceAll(str, "http://", "")
+			str = strings.ReplaceAll(str, ":8060/", "")
+			// Location: http://192.168.1.134:8060/
+			list = append(list, str)
+		}
+	}
+	return list
+}
+
 func Get(where string) *http.Response {
 	resp, err := http.Get(where)
 	if err != nil {
@@ -40,7 +118,8 @@ func Query(ip, what string) string {
 }
 
 func PerformKey(ip, command string) {
-	Post(KeyPress(ip, command))
+	r := Post(KeyPress(ip, command))
+	defer r.Body.Close()
 }
 
 func GetCurrentPlay(ip string) map[string]interface{} {
@@ -57,6 +136,7 @@ func GetCurrentPlay(ip string) map[string]interface{} {
 	if err != nil {
 		log.Printf("Got a error parsing XML, %v", err)
 	}
+	defer resp.Body.Close()
 	return r
 }
 
@@ -74,9 +154,16 @@ func GetQuery(ip, command string) map[string]interface{} {
 	if err != nil {
 		log.Printf("Got a error parsing XML, %v", err)
 	}
+	defer resp.Body.Close()
 	return r
 }
 
+func GetDevices() []string {
+	str := GetFind()
+	//fmt.Print(str)
+	return str
+}
+
 func DebugInfo(ip string) string {
 	// Query the current playing thing, and get the tv channels
 	r := GetQuery(ip, "media-player")

+ 28 - 0
templates/connect.html

@@ -0,0 +1,28 @@
+<!doctype html>
+<html>
+    <head>
+        <meta charset="utf-8">
+        <meta http-equiv="x-ua-compatible" content="ie=edge">
+        <meta name="viewport" content="width=device-width, initial-scale=1.0">
+        <title>goRoku Controller</title>
+        <!--<link rel="stylesheet" href="static/css/foundation.css">-->
+        <link rel="stylesheet" href="css/foundation.css">
+    </head>
+    <body>
+        <div class="grid-x">
+            <h1 class="large-12 medium-12 small-12 cell text-center">goRoku Connection</h1>
+            <div class="large-12 medium-12 small-12 cell text-center">
+                <button type="button" class="button" onclick="sendTo('/')">Back to Remote</button> <button type="button" class="button" onclick="sendTo('/conn_refresh')">Reload</button><br>
+                <p>{{.connected}}</p><br>
+                {{range .resp}}
+                    <button type="button" class="button" onclick="sendTo('/con/{{.}}')">{{.}}</button><br>
+                {{end}}
+            </div>
+        </div>
+        <script>
+            function sendTo(cmd) {
+                location = cmd;
+            }
+        </script>
+    </body>
+</html>

+ 4 - 1
templates/index.html

@@ -14,7 +14,7 @@
             <div class="large-12 medium-12 small-12 cell text-center">
                 <h3 id="at">TV</h3>
                 <p>
-                    <button type="button" class="alert button" onclick="sendCommandTV('power')">Power</button> <button type="button" class="alert button" onclick="sendCommandTV('display')">Display</button><br>
+                    <button type="button" class="alert button" onclick="sendCommandTV('power')">Power</button> <button type="button" class="alert button" onclick="sendCommandTV('display')">Display</button> <button type="button", class="button", onclick="sendTo('/connect')">Connect</button><br>
                     <button type="button" class="button" onclick="sendCommandTV('back')">Back</button> <button type="button" class="button" onclick="sendCommandTV('home')">Home</button><br>
                     <button type="button" class="button" onclick="sendCommandTV('up')">^</button><br>
                     <button type="button" class="button" onclick="sendCommandTV('left')"><</button> <button type="button" class="success button" onclick="sendCommandTV('ok')">Ok</button> <button type="button" class="button" onclick="sendCommandTV('right')">></button><br>
@@ -52,6 +52,9 @@
                 xhttp.send();
 
             }
+            function sendTo(cmd) {
+                location = cmd;
+            }
             /*function sendCommandMB(cmd) {
                 const xhttp = new XMLHttpRequest();
                 xhttp.onload = function() {}

+ 61 - 30
webserver.go

@@ -2,6 +2,7 @@ package main
 
 import (
 	"fmt"
+	"log"
 	"net/http"
 
 	"github.com/labstack/echo/v4"
@@ -9,17 +10,17 @@ import (
 )
 
 type WebServer struct {
-	tv_ip string
-	Port  string
-	Host  string
-	At    string
+	Tv_ip       string
+	Port        string
+	Host        string
+	At          string
+	Device_list []string
 }
 
 func (w *WebServer) Init(tv, host, port string) {
-	w.tv_ip = tv
+	w.Tv_ip = tv
 	w.Host = host
 	w.Port = port
-	w.At = DebugInfo(w.tv_ip)
 }
 
 func (w *WebServer) homepage(c echo.Context) error {
@@ -35,59 +36,84 @@ func (w *WebServer) homepage(c echo.Context) error {
 	return c.Render(http.StatusOK, "index.html", data)
 }
 
+func (w *WebServer) connectpage(c echo.Context) error {
+	data := make(map[string]interface{})
+	data["connected"] = "Connected: " + w.Tv_ip
+	//var dev_list []string
+	var list []string
+	list = append(list, w.Device_list...)
+	data["resp"] = list
+	return c.Render(http.StatusOK, "connect.html", data)
+}
+
+func (w *WebServer) connector(c echo.Context) error {
+	cmd := c.Param("cmd")
+	w.Tv_ip = cmd
+	log.Printf("Switched to %s", cmd)
+
+	return c.Redirect(http.StatusOK, "/connect")
+}
+
+func (w *WebServer) con_refresh(c echo.Context) error {
+	log.Printf("Recieved Connection Refresh")
+	w.Device_list = GetDevices()
+	log.Printf("Found %d devices", len(w.Device_list))
+	return c.Redirect(http.StatusOK, "/connect")
+}
+
 func (w *WebServer) tvcmd(c echo.Context) error {
-	//w.At = DebugInfo(w.tv_ip)
+	//w.At = DebugInfo(w.Tv_ip)
 	cmd := c.Param("cmd")
 	switch cmd {
 	case "power":
-		PerformKey(w.tv_ip, "power")
+		PerformKey(w.Tv_ip, "power")
 	case "back":
-		PerformKey(w.tv_ip, "back")
+		PerformKey(w.Tv_ip, "back")
 	case "home":
-		PerformKey(w.tv_ip, "home")
+		PerformKey(w.Tv_ip, "home")
 	case "up":
-		PerformKey(w.tv_ip, "up")
+		PerformKey(w.Tv_ip, "up")
 	case "left":
-		PerformKey(w.tv_ip, "left")
+		PerformKey(w.Tv_ip, "left")
 	case "ok":
-		PerformKey(w.tv_ip, "select")
+		PerformKey(w.Tv_ip, "select")
 	case "right":
-		PerformKey(w.tv_ip, "right")
+		PerformKey(w.Tv_ip, "right")
 	case "down":
-		PerformKey(w.tv_ip, "down")
+		PerformKey(w.Tv_ip, "down")
 	case "rewind":
-		PerformKey(w.tv_ip, "rev")
+		PerformKey(w.Tv_ip, "rev")
 	case "play-pause":
-		PerformKey(w.tv_ip, "play")
+		PerformKey(w.Tv_ip, "play")
 	case "fast-forward":
-		PerformKey(w.tv_ip, "fwd")
+		PerformKey(w.Tv_ip, "fwd")
 	case "star":
-		PerformKey(w.tv_ip, "info")
+		PerformKey(w.Tv_ip, "info")
 	case "reload":
-		PerformKey(w.tv_ip, "instantreplay")
+		PerformKey(w.Tv_ip, "instantreplay")
 	case "vol+":
-		PerformKey(w.tv_ip, "volumeup")
+		PerformKey(w.Tv_ip, "volumeup")
 	case "vol-":
-		PerformKey(w.tv_ip, "volumedown")
+		PerformKey(w.Tv_ip, "volumedown")
 	case "mute":
-		PerformKey(w.tv_ip, "volumemute")
+		PerformKey(w.Tv_ip, "volumemute")
 	case "display":
-		w.At = DebugInfo(w.tv_ip)
+		w.At = DebugInfo(w.Tv_ip)
 		data := make(map[string]interface{})
 		data["at"] = w.At
 		return c.String(http.StatusOK, w.At)
 	case "pluto":
-		Post(fmt.Sprintf("http://%s:8060/launch/%d", w.tv_ip, 74519))
+		Post(fmt.Sprintf("http://%s:8060/launch/%d", w.Tv_ip, 74519))
 	case "pluto-cops":
-		Post(fmt.Sprintf("http://%s:8060/launch/%d?contentId=367&mediaType=live", w.tv_ip, 74519))
+		Post(fmt.Sprintf("http://%s:8060/launch/%d?contentId=367&mediaType=live", w.Tv_ip, 74519))
 	case "pluto-thefirst":
-		Post(fmt.Sprintf("http://%s:8060/launch/%d?contentId=244&mediaType=live", w.tv_ip, 74519))
+		Post(fmt.Sprintf("http://%s:8060/launch/%d?contentId=244&mediaType=live", w.Tv_ip, 74519))
 	case "pluto-mst3k":
-		Post(fmt.Sprintf("http://%s:8060/launch/%d?contentId=488&mediaType=live", w.tv_ip, 74519))
+		Post(fmt.Sprintf("http://%s:8060/launch/%d?contentId=488&mediaType=live", w.Tv_ip, 74519))
 	case "pluto-rifftrax":
-		Post(fmt.Sprintf("http://%s:8060/launch/%d?contentId=489&mediaType=live", w.tv_ip, 74519))
+		Post(fmt.Sprintf("http://%s:8060/launch/%d?contentId=489&mediaType=live", w.Tv_ip, 74519))
 	case "pluto-startrek":
-		Post(fmt.Sprintf("http://%s:8060/launch/%d?contentId=150&mediaType=live", w.tv_ip, 74519))
+		Post(fmt.Sprintf("http://%s:8060/launch/%d?contentId=150&mediaType=live", w.Tv_ip, 74519))
 	default:
 		c.Echo().Logger.Printf("Got '%v'\r\n", cmd)
 	}
@@ -102,7 +128,12 @@ func main() {
 	e.Use(middleware.Logger())
 	e.Use(middleware.Static("static"))
 	e.Renderer = NewRenderer("./templates/*.html", true)
+
 	e.GET("/", web.homepage)
 	e.GET("/tv/:cmd", web.tvcmd)
+	e.GET("/connect", web.connectpage)
+	e.GET("/con/:cmd", web.connector)
+	e.GET("/conn_refresh", web.con_refresh)
+
 	e.Logger.Fatal(e.Start(fmt.Sprintf("%s:%s", web.Host, web.Port)))
 }