Created
August 27, 2016 04:12
-
-
Save chazcheadle/94f9543b36cad8ea4a0f9c9ba7451cd2 to your computer and use it in GitHub Desktop.
Publish JSON endpoint to list available camera resources (HTTP 200) loaded from a YAML config file written in Golang
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
| cameras: | |
| Exterior (South): | |
| camera_id: hab_camera-1 | |
| url : http://HOST:8091/?action=stream | |
| low_image : http://HOST:8091/low.png | |
| type : mjpeg-streamer | |
| Exterior IR (South): | |
| camera_id: hab_camera-2 | |
| url : http://HOST:8090/?action=stream | |
| low_image : http://HOST:8090/low.png | |
| type : mjpeg-streamer | |
| Exterior (North): | |
| camera_id: hab_camera-3 | |
| url : http://HOST:8092/?action=stream | |
| low_image : http://HOST:8092/low.png | |
| type : mjpeg-streamer | |
| Garden (East): | |
| camera_id: hab_camera-4 | |
| url : http://HOST:8081 | |
| low_image : http://HOST:8081/low.png | |
| type : motion |
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" | |
| "io/ioutil" | |
| "net/http" | |
| "net/url" | |
| "os" | |
| "sync" | |
| "gopkg.in/yaml.v2" | |
| log "github.com/Sirupsen/logrus" | |
| ) | |
| type config struct { | |
| Cameras map[string]camera | |
| } | |
| type camera struct { | |
| CameraId string `yaml:"camera_id" json:"camera_id"` | |
| Url string `yaml:"url" json:"url"` | |
| Low string `yaml:"low_image" json:"low"` | |
| Type string `yaml:"type" json:"type"` | |
| } | |
| func testCameras(conf *config) (availableCameras *config) { | |
| var wg sync.WaitGroup | |
| wg.Add(len(conf.Cameras)) | |
| for name, settings := range conf.Cameras { | |
| Url := settings.Url | |
| go func(name string, Url string) { | |
| defer wg.Done() | |
| // Make sure the URL is properly formatted. | |
| _, err := url.Parse(Url) | |
| if err != nil { | |
| log.Warn("Invalid URL: ", Url) | |
| delete(conf.Cameras, name) | |
| } else { | |
| response, err := http.Get(Url) | |
| if err != nil { | |
| log.Warn("Unable to get response from: ", Url) | |
| log.Warn(err) | |
| delete(conf.Cameras, name) | |
| } else if response.StatusCode != http.StatusOK { | |
| fmt.Println("Not OK") | |
| delete(conf.Cameras, name) | |
| } | |
| } | |
| }(name, Url) | |
| } | |
| wg.Wait() | |
| return conf | |
| } | |
| // Get configuration of cameras from yaml file. | |
| func getConfig() (*config, error) { | |
| confFile := "/opt/chab/modules/camera/cameras.yml" | |
| if len(os.Args[1:]) > 0 { | |
| confFile = os.Args[1] | |
| } | |
| conf := &config{} | |
| f, err := os.Open(confFile) | |
| defer f.Close() | |
| if err != nil { | |
| log.Info("Could not open %s.", confFile) | |
| log.Info("Error: ", err) | |
| } | |
| d, err := ioutil.ReadAll(f) | |
| if err != nil { | |
| log.Info("Error reading %s.", confFile) | |
| log.Info("Error: ", err) | |
| } | |
| err = yaml.Unmarshal(d, conf) | |
| if err != nil { | |
| log.Info("Error: ", err) | |
| log.Info("Could not parse ", confFile) | |
| } | |
| return conf, err | |
| } | |
| func structToArray(availableCameras *config) (cameraList []byte) { | |
| cameraList, _ = json.Marshal(availableCameras) | |
| return cameraList | |
| } | |
| func main() { | |
| // Get configuration. | |
| conf, err := getConfig() | |
| if err != nil { | |
| log.Fatal("Failed to get configuration\n", err) | |
| } | |
| // Test cameras. | |
| availableCameras := testCameras(conf) | |
| cameraList := structToArray(availableCameras) | |
| http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { | |
| w.Header().Set("Content-Type", "application/json") | |
| w.Header().Set("Access-Control-Allow-Origin", "*") | |
| w.Write(cameraList) | |
| }) | |
| http.ListenAndServe(":3000", nil) | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
TODO: Change wait group to NewTicker?