Skip to content

Commit

Permalink
Added input option
Browse files Browse the repository at this point in the history
  • Loading branch information
linuxfreak003 committed Aug 21, 2020
1 parent 2bc2ba4 commit 1f2152f
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 50 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@
go.sum
roku
!roku/
*.swp
133 changes: 88 additions & 45 deletions roku.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"io/ioutil"
"log"
"net/http"
"net/url"
"time"

ssdp "github.com/bcurren/go-ssdp"
Expand Down Expand Up @@ -213,9 +214,14 @@ func (r *Remote) Install(app *App) error {
return r.install(app.Id)
}

// Input sends input (not implemented yet)
func (r *Remote) Input(in string) error {
return r.input(in)
// Input sends a string of input
// (useful for things like filling a search box)
func (r *Remote) InputString(in string) error {
return r.literal_input(in)
}

func (r *Remote) InputRune(rn rune) error {
return r.literal_input(string(rn))
}

// Apps will get all installed apps fromt he device
Expand Down Expand Up @@ -262,53 +268,78 @@ func (r *Remote) PlayerStatus() (*PlayerStatus, error) {
return status, err
}

// All of the following methods
// correspond to a keypress event
func (r *Remote) Home() error { return r.keypress("Home") }
func (r *Remote) Rev() error { return r.keypress("Rev") }
func (r *Remote) Fwd() error { return r.keypress("Fwd") }
func (r *Remote) Play() error { return r.keypress("Play") }
func (r *Remote) Select() error { return r.keypress("Select") }
func (r *Remote) Left() error { return r.keypress("Left") }
func (r *Remote) Right() error { return r.keypress("Right") }
func (r *Remote) Down() error { return r.keypress("Down") }
func (r *Remote) Up() error { return r.keypress("Up") }
func (r *Remote) Back() error { return r.keypress("Back") }
// Equivalent of pressing Home button on the remote
func (r *Remote) Home() error { return r.keypress("Home") }

// Equivalent of pressing Rev button on the remote
func (r *Remote) Rev() error { return r.keypress("Rev") }

// Equivalent of pressing Fwd button on the remote
func (r *Remote) Fwd() error { return r.keypress("Fwd") }

// Equivalent of pressing Play button on the remote
func (r *Remote) Play() error { return r.keypress("Play") }

// Equivalent of pressing Select button on the remote
func (r *Remote) Select() error { return r.keypress("Select") }

// Equivalent of pressing Left button on the remote
func (r *Remote) Left() error { return r.keypress("Left") }

// Equivalent of pressing Right button on the remote
func (r *Remote) Right() error { return r.keypress("Right") }

// Equivalent of pressing Down button on the remote
func (r *Remote) Down() error { return r.keypress("Down") }

// Equivalent of pressing Up button on the remote
func (r *Remote) Up() error { return r.keypress("Up") }

// Equivalent of pressing Back button on the remote
func (r *Remote) Back() error { return r.keypress("Back") }

// Equivalent of pressing Instant Replay button on the remote
func (r *Remote) InstantReplay() error { return r.keypress("InstantReplay") }
func (r *Remote) Info() error { return r.keypress("Info") }
func (r *Remote) Backspace() error { return r.keypress("Backspace") }
func (r *Remote) Search() error { return r.keypress("Search") }
func (r *Remote) Enter() error { return r.keypress("Enter") }

// The following keypresses are
// only available on some devices
func (r *Remote) VolumeDown() error { return r.keypress("VolumeDown") }
func (r *Remote) VolumeMute() error { return r.keypress("VolumeMute") }
func (r *Remote) VolumeUp() error { return r.keypress("VolumeUp") }
func (r *Remote) PowerOff() error { return r.keypress("PowerOff") }
func (r *Remote) PowerOn() error { return r.keypress("PowerOn") }
func (r *Remote) ChannelUp() error { return r.keypress("ChannelUp") }
func (r *Remote) ChannelDown() error { return r.keypress("ChannelDown") }

// helper method for hitting the `input` endpoint
// currently unimplemented
func (r *Remote) input(in string) error {
URL := fmt.Sprintf("http://%s/input", r.Addr)
client := &http.Client{}
// Equivalent of pressing Info button on the remote
func (r *Remote) Info() error { return r.keypress("Info") }

req, err := http.NewRequest(http.MethodPost, URL, nil)
if err != nil {
return fmt.Errorf("could not build HTTP request: %v", err)
}
// Equivalent of pressing Backspace button on the remote
func (r *Remote) Backspace() error { return r.keypress("Backspace") }

resp, err := client.Do(req)
if err != nil {
return fmt.Errorf("could not send HTTP request: %v", err)
}
defer resp.Body.Close()
// Equivalent of pressing Search button on the remote
func (r *Remote) Search() error { return r.keypress("Search") }

return nil
}
// Equivalent of pressing Enter button on the remote
func (r *Remote) Enter() error { return r.keypress("Enter") }

// Equivalent of pressing Volume Down button on the remote
// not available on all devices
func (r *Remote) VolumeDown() error { return r.keypress("VolumeDown") }

// Equivalent of pressing Mute button on the remote
// not available on all devices
func (r *Remote) VolumeMute() error { return r.keypress("VolumeMute") }

// Equivalent of pressing Volume Up button on the remote
// not available on all devices
func (r *Remote) VolumeUp() error { return r.keypress("VolumeUp") }

// Equivalent of pressing Power button on the remote
// not available on all devices
func (r *Remote) PowerOff() error { return r.keypress("PowerOff") }

// Equivalent of pressing Power button on the remote
// not available on all devices
func (r *Remote) PowerOn() error { return r.keypress("PowerOn") }

// Equivalent of pressing Channel Up button on the remote
// not available on all devices
func (r *Remote) ChannelUp() error { return r.keypress("ChannelUp") }

// Equivalent of pressing Channel Down button on the remote
// not available on all devices
func (r *Remote) ChannelDown() error { return r.keypress("ChannelDown") }

// helper method for hitting the `install` endpoint
func (r *Remote) install(appId string) error {
Expand Down Expand Up @@ -367,6 +398,18 @@ func (r *Remote) query(cmd string) ([]byte, error) {
return ioutil.ReadAll(resp.Body)
}

// helper method for entering literal input
func (r *Remote) literal_input(input string) error {
for _, c := range input {
escaped := url.QueryEscape(string(c))
err := r.keypress("Lit_" + escaped)
if err != nil {
return err
}
}
return nil
}

// helper method for hitting the `keypress` endpoint
func (r *Remote) keypress(cmd string) error {
URL := fmt.Sprintf("http://%s/keypress/%s", r.Addr, cmd)
Expand Down
37 changes: 32 additions & 5 deletions roku/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ var UsageMessage = ` +----------------------------------+-----------------------
| Volume Mute m | Home H |
| Power Off/On p | Info/Settings i |
| List Apps a | Player Status s |
| Enter Input / | |
+---------------------------------+----------------------------------+
(press q, Esc, or Ctrl-C to exit)`

Expand Down Expand Up @@ -124,11 +125,11 @@ func main() {
}

func CommandLoop(r *roku.Remote) {
fmt.Printf("> ")

for {
var err error

fmt.Printf("> ")

char, key, err := keyboard.GetKey()
if err != nil {
log.Fatalf("error getting key event: %v", err)
Expand All @@ -139,8 +140,30 @@ func CommandLoop(r *roku.Remote) {
}

switch key {
case keyboard.KeyEsc, keyboard.KeyCtrlC, 'q':
case keyboard.KeyEsc, keyboard.KeyCtrlC, keyboard.KeyCtrlD, 'q':
return
case '/':
fmt.Printf("Enter Text: ")

s := ""

for char, key, err = keyboard.GetKey(); key != keyboard.KeyEnter; char, key, err = keyboard.GetKey() {
if err != nil {
break
}

val := string(key)
if key == 0 {
val = string(char)
}

fmt.Printf("%s", val)
s += val
}

err = r.InputString(s + "\n")

fmt.Printf("\n> ")
case keyboard.KeyArrowLeft, 'h':
err = r.Left()
case keyboard.KeyArrowDown, 'j':
Expand All @@ -155,7 +178,7 @@ func CommandLoop(r *roku.Remote) {
err = r.Play()
case keyboard.KeyEnter:
err = r.Select()
case keyboard.KeyBackspace, 'B', 'u':
case keyboard.KeyBackspace, keyboard.KeyBackspace2, 'B', 'u':
err = r.Back()
case '+', keyboard.KeyCtrlK:
err = r.VolumeUp()
Expand All @@ -179,17 +202,20 @@ func CommandLoop(r *roku.Remote) {
for _, app := range apps {
fmt.Printf("[%s]\t%s\n", app.Id, app.Name)
}

fmt.Printf("> ")
}
case 's':
var ps *roku.PlayerStatus

ps, err = r.PlayerStatus()
if err == nil {
fmt.Printf("App: [%s] %s\n", ps.Plugin.Id, ps.Plugin.Name)
fmt.Printf("Media Player\nApp: [%s] %s\n", ps.Plugin.Id, ps.Plugin.Name)
fmt.Printf("Error: %v State: %s\n", ps.Error, ps.State)
fmt.Printf("Bandwidth: %s\n", ps.Plugin.Bandwidth)
fmt.Printf("Position: %s\n", ps.Position)
fmt.Printf("Live: %v\n", ps.IsLive)
fmt.Printf("> ")
}
case 'p':
if r.Device.PowerMode == "PowerOn" {
Expand All @@ -201,6 +227,7 @@ func CommandLoop(r *roku.Remote) {
_ = r.Refresh()
default:
log.Printf("'%s' key does not match any command", string(key))
fmt.Printf("> ")
}

LogIf(err)
Expand Down

0 comments on commit 1f2152f

Please sign in to comment.