poster.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. package main
  2. import (
  3. "fmt"
  4. "io"
  5. "log"
  6. "net/http"
  7. "strings"
  8. "fyne.io/fyne/v2"
  9. "github.com/beego/x2j"
  10. )
  11. // https://zetcode.com/golang/getpostrequest/ post_req_form.go
  12. func Post(where string) *http.Response {
  13. resp, err := http.PostForm(where, nil)
  14. if err != nil {
  15. log.Printf("POST got non 200 code, %v", err)
  16. // Catch what error it is, if it's a no access to device try a etherwake
  17. return nil
  18. }
  19. return resp
  20. }
  21. /*func ListenToRequests(ln *net.UDPConn, data *string) {
  22. done := false
  23. do_send := true
  24. for !done {
  25. buffer := make([]byte, 1024) // 1k
  26. ln.SetReadDeadline(time.Now().Add(3 * time.Second))
  27. for !done {
  28. b, _, err := ln.ReadFromUDP(buffer)
  29. if b > 0 {
  30. str := string(buffer[0:])
  31. *data += str
  32. }
  33. if err != nil {
  34. if _, ok := err.(net.Error); !ok {
  35. log.Print(err)
  36. done = true
  37. }
  38. }
  39. if do_send {
  40. err = PostFind()
  41. if err != nil {
  42. log.Printf("POST Find returned %v", err)
  43. }
  44. do_send = false
  45. }
  46. }
  47. }
  48. }*/
  49. /*
  50. func PostFind() {
  51. file, err := os.ReadFile("finder.txt")
  52. if err != nil {
  53. log.Print(err)
  54. }
  55. addr, err := net.ResolveUDPAddr("udp", "239.255.255.250:1900")
  56. if err != nil {
  57. log.Print(err)
  58. }
  59. conn, err := net.DialUDP("udp", nil, addr)
  60. if err != nil {
  61. log.Print(err)
  62. }
  63. defer conn.Close()
  64. conn.Write(file)
  65. log.Println("Posted Request for devices")
  66. }
  67. func GetFind(data *[]string) {
  68. addr, err := net.ResolveUDPAddr("udp", ":1900")
  69. if err != nil {
  70. log.Printf("GET Find failed getting port 1900, %v", err)
  71. return
  72. }
  73. fmt.Printf("Listening on %s\r\n", addr.String())
  74. ln, err := net.ListenUDP("udp", addr)
  75. if err != nil {
  76. log.Printf("GET Find started listener for 1900, %v", err)
  77. return
  78. }
  79. var list []string
  80. buffer := make([]byte, 1024) // 1k
  81. defer ln.Close()
  82. ln.SetReadDeadline(time.Now().Add(3 * time.Second))
  83. for {
  84. n, adr, err := ln.ReadFromUDP(buffer)
  85. str := string(buffer[0:n])
  86. fmt.Printf("Got '%s' from %s\r\n", str, adr.String())
  87. if err != nil {
  88. log.Println(err)
  89. break
  90. }
  91. list = append(list, adr.String())
  92. }
  93. *data = list
  94. }
  95. */
  96. func Get(where string) *http.Response {
  97. resp, err := http.Get(where)
  98. if err != nil {
  99. log.Printf("GET got non 200 code, %v", err)
  100. return nil
  101. } else {
  102. return resp
  103. }
  104. }
  105. // https://developer.roku.com/docs/developer-program/debugging/external-control-api.md#keypress-key-values codes
  106. func KeyPress(ip, command string) string {
  107. return fmt.Sprintf("http://%s:8060/keypress/%s", ip, command)
  108. }
  109. // https://developer.roku.com/docs/developer-program/debugging/external-control-api.md#general-ecp-commands
  110. func Query(ip, what string) string {
  111. return fmt.Sprintf("http://%s:8060/query/%s", ip, what)
  112. }
  113. func PerformKey(ip, command string) bool {
  114. r := Post(KeyPress(ip, command))
  115. if r == nil {
  116. return false
  117. }
  118. defer r.Body.Close()
  119. return true
  120. }
  121. func GetQuery(ip, command string) []byte {
  122. var resp *http.Response = Get(Query(ip, command))
  123. if resp == nil {
  124. return nil
  125. }
  126. var body []byte
  127. var err error
  128. body, err = io.ReadAll(resp.Body)
  129. if err != nil {
  130. log.Printf("Reading from body got error, %v", err)
  131. }
  132. defer resp.Body.Close()
  133. return body
  134. }
  135. func GetCurrentPlay(ip string) *MediaPlayer {
  136. var resp []byte = GetQuery(ip, "media-player")
  137. var mp MediaPlayer
  138. var err error = x2j.Unmarshal(resp, &mp)
  139. if err != nil {
  140. log.Printf("Error occurred processing XML, %v", err)
  141. }
  142. return &mp
  143. }
  144. func ObtainDeviceInfo(ip string) *DeviceInfo {
  145. var resp []byte = GetQuery(ip, "device-info")
  146. var di DeviceInfo
  147. var err error = x2j.Unmarshal(resp, &di)
  148. if err != nil {
  149. log.Printf("Error occurred processing XML, %v", err)
  150. }
  151. return &di
  152. }
  153. // Returns a map of device-infos
  154. func GetDeviceInfo(ip string) *DeviceInfo {
  155. var di *DeviceInfo = ObtainDeviceInfo(ip)
  156. /*keys := glom.GetPossible(dev)
  157. for _, key := range keys {
  158. log.Printf("%s = %v", key, dev[key])
  159. }*/
  160. return di
  161. }
  162. func GetDevices(wake_on_lan map[string]string, w fyne.Window) ([]string, map[string]string) {
  163. var str []string
  164. resp := strings.Split(PostFind(w), "\n")
  165. //fmt.Printf("Processing %d lines\n", len(resp))
  166. ip := ""
  167. for _, line := range resp {
  168. if strings.Contains(line, "LOCATION") {
  169. st := strings.ReplaceAll(line, "LOCATION: http://", "")
  170. st = strings.ReplaceAll(st, ":8060/", "")
  171. st = strings.ReplaceAll(st, "\r", "")
  172. //fmt.Printf("IP='%s'", st)
  173. str = append(str, st)
  174. ip = st
  175. } else if strings.Contains(line, "WAKEUP") {
  176. st := strings.ReplaceAll(line, "WAKEUP: MAC=", "")
  177. st = strings.ReplaceAll(st, ";Timeout=10", "")
  178. st = strings.ReplaceAll(st, "\r", "")
  179. //fmt.Printf("IP='%s' MAC='%s'", ip, st)
  180. wake_on_lan[ip] = st
  181. }
  182. }
  183. return str, wake_on_lan
  184. }
  185. func DebugInfo(ip string) string {
  186. // Query the current playing thing, and get the tv channels
  187. var mp *MediaPlayer = GetCurrentPlay(ip)
  188. var name string
  189. var id string
  190. /*r1 := GetQuery(ip, "tv-channels")
  191. chan_name, _ := glom.Glom(r1, "tv-channels.channel.name")
  192. chan_phy_id, _ := glom.Glom(r1, "tv-channels.channel.physical-channel")
  193. chan_number, _ := glom.Glom(r1, "tv-channels.channel.number")*/
  194. if mp.Plugin.Name == "" && mp.Plugin.Id == 0 {
  195. name = "TV"
  196. id = "Off"
  197. } else {
  198. name = mp.Plugin.Name
  199. id = fmt.Sprintf("%d", mp.Plugin.Id)
  200. }
  201. // Debug print
  202. fmt.Printf("Name: %v (%v)\r\n", name, id)
  203. //fmt.Printf("Channel: %v (%v / %v)\r\n", chan_name, chan_phy_id, chan_number)
  204. return fmt.Sprintf("%v (%v)", name, id)
  205. }