Skip to content

Instantly share code, notes, and snippets.

@nasa9084
Created July 30, 2019 14:33
Show Gist options
  • Select an option

  • Save nasa9084/c482f43cc9ee0644782f8c75013fc778 to your computer and use it in GitHub Desktop.

Select an option

Save nasa9084/c482f43cc9ee0644782f8c75013fc778 to your computer and use it in GitHub Desktop.
IR API server
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"os"
"os/exec"
)
const (
codeFilename = "/home/pi/codes"
irrpPyFilename = "/home/pi/irrp.py"
)
func Read(key string) ([]byte, error) {
out, err := exec.Command("python3", irrpPyFilename, "-r", "-g25", "-f", codeFilename, key, "--no-confirm", "--post", "130").Output()
if err != nil {
return nil, err
}
if len(out) != 0 {
log.Println(out)
}
return out, nil
}
func Playback(key string) ([]byte, error) {
out, err := exec.Command("python3", irrpPyFilename, "-p", "-g17", "-f", codeFilename, key).Output()
if err != nil {
return nil, err
}
if len(out) != 0 {
log.Println(out)
}
return out, nil
}
func IsRegistered(key string) (bool, error) {
f, err := os.Open(codeFilename)
if err != nil {
return false, err
}
defer f.Close()
var codes map[string][]uint
if err := json.NewDecoder(f).Decode(&codes); err != nil {
return false, err
}
_, ok := codes[key]
return ok, nil
}
// readHandler is a http.HandlerFunc which reads IR signals.
// This handler accepts POST method, requires "key" key in body with x-www-form-urlencoded or json.
func readHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
w.WriteHeader(http.StatusMethodNotAllowed)
w.Write([]byte(fmt.Sprintf("POST is expected but %s", r.Method)))
return
}
var key string
if ctype := r.Header.Get("Content-Type"); ctype == "application/x-www-form-urlencoded" {
key = r.PostFormValue("key")
if key == "" {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(`Content-Type is application/x-www-form-urlencoded but cannot find "key"`))
return
}
} else {
var body struct {
Key string `json:"key"`
}
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
w.WriteHeader(http.StatusBadRequest)
if ctype == "application/json" {
w.Write([]byte(fmt.Sprintf(`Content-Type is application/json but cannot decode as json: %s`, err.Error())))
} else {
w.Write([]byte(fmt.Sprintf(`Content-Type is unknown type %s so tried to decode as json but cannot decode: %s`, ctype, err.Error())))
}
log.Printf("ERROR: %+v", err)
return
}
key = body.Key
}
isRegistered, err := IsRegistered(key)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
return
}
out, err := Read(key)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Printf("ERROR: %+v", err)
w.Write([]byte(err.Error()))
return
}
w.WriteHeader(http.StatusOK)
if isRegistered {
w.Write([]byte(fmt.Sprintf("WARN: given key %s exists. it was overwritten")))
}
w.Write(out)
}
// playbackHandler is a http.HandlerFunc which playback IR signal.
// This handler accepts GET method, requires "key" key in query.
func playbackHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
w.WriteHeader(http.StatusMethodNotAllowed)
w.Write([]byte(fmt.Sprintf("GET is expected but %s", r.Method)))
return
}
key := r.FormValue("key")
if key == "" {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(`"key" is not given`))
return
}
isRegistered, err := IsRegistered(key)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
return
}
if !isRegistered {
w.WriteHeader(http.StatusNotFound)
w.Write([]byte(fmt.Sprintf("given key %s has not registered. please register first.", key)))
return
}
out, err := Playback(key)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Printf("ERROR: %+v", err)
w.Write([]byte(err.Error()))
return
}
w.WriteHeader(http.StatusOK)
w.Write(out)
}
func main() {
log.Println("start irrp server")
http.HandleFunc(`/`, func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte(`hello, world`))
})
http.HandleFunc(`/read`, readHandler)
http.HandleFunc(`/playback`, playbackHandler)
log.Printf("listen at :8080")
if err := http.ListenAndServe(":8080", nil); err != nil {
log.Printf("error: %+v", err)
os.Exit(1)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment