Created
July 30, 2019 14:33
-
-
Save nasa9084/c482f43cc9ee0644782f8c75013fc778 to your computer and use it in GitHub Desktop.
IR API server
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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