started cleaning up the code API

This commit is contained in:
Matt Aimonetti 2014-04-26 10:13:33 -06:00 committed by Adrian Zankich
parent 28d0d5178b
commit d4f6d06003
6 changed files with 119 additions and 91 deletions

107
api.go
View File

@ -2,73 +2,74 @@ package gobot
import (
"encoding/json"
"github.com/go-martini/martini"
"github.com/martini-contrib/auth"
"github.com/martini-contrib/cors"
"io/ioutil"
"log"
"net/http"
"reflect"
"github.com/go-martini/martini"
"github.com/martini-contrib/auth"
"github.com/martini-contrib/cors"
)
type startFuncAlias func(*api)
// Optional restful API through the master to access
// all the robots.
type api struct {
master *Master
server *martini.ClassicMartini
Host string
Port string
Username string
Password string
Cert string
Key string
master *Master
server *martini.ClassicMartini
Host string
Port string
Username string
Password string
Cert string
Key string
startFunc startFuncAlias
}
type jsonRobot struct {
Name string `json:"name"`
Commands []string `json:"commands"`
Connections []*jsonConnection `json:"connections"`
Devices []*jsonDevice `json:"devices"`
func NewApi() *api {
return &api{startFunc: defaultStartFunc}
}
type jsonDevice struct {
Name string `json:"name"`
Driver string `json:"driver"`
Connection *jsonConnection `json:"connection"`
Commands []string `json:"commands"`
}
type jsonConnection struct {
Name string `json:"name"`
Port string `json:"port"`
Adaptor string `json:"adaptor"`
}
var startApi = func(me *api) {
username := me.Username
if username != "" {
password := me.Password
me.server.Use(auth.Basic(username, password))
var defaultStartFunc = func(a *api) {
if a == nil {
return
}
port := me.Port
username := a.Username
if username != "" {
password := a.Password
a.server.Use(auth.Basic(username, password))
}
port := a.Port
if port == "" {
port = "3000"
}
host := me.Host
cert := me.Cert
key := me.Key
host := a.Host
cert := a.Cert
key := a.Key
log.Println("Initializing API on " + host + ":" + port + "...")
if cert != "" && key != "" {
go http.ListenAndServeTLS(host+":"+port, cert, key, me.server)
} else {
log.Println("WARNING: API using insecure connection. We recommend using an SSL certificate with Gobot.")
go http.ListenAndServe(host+":"+port, me.server)
}
go func() {
if cert != "" && key != "" {
http.ListenAndServeTLS(host+":"+port, cert, key, a.server)
} else {
log.Println("WARNING: API using insecure connection. We recommend using an SSL certificate with Gobot.")
http.ListenAndServe(host+":"+port, a.server)
}
}()
}
func (me *api) startApi() {
startApi(me)
// start starts the api using the start function
// sets on the API on initialization.
func (a *api) start() {
if a == nil {
return
}
a.startFunc(a)
}
func Api(bot *Master) *api {
@ -171,13 +172,13 @@ func (me *api) robot_devices(name string, res http.ResponseWriter, req *http.Req
}
func (me *api) robot_device(robot string, device string, res http.ResponseWriter, req *http.Request) {
data, _ := json.Marshal(me.formatJsonDevice(me.master.FindRobotDevice(robot, device)))
data, _ := json.Marshal(me.formatJsonDevice(me.master.FindRobot(robot).GetDevice(device)))
res.Header().Set("Content-Type", "application/json; charset=utf-8")
res.Write(data)
}
func (me *api) robot_device_commands(robot string, device string, res http.ResponseWriter, req *http.Request) {
data, _ := json.Marshal(me.master.FindRobotDevice(robot, device).Commands())
data, _ := json.Marshal(me.master.FindRobot(robot).GetDevice(device).Commands())
res.Header().Set("Content-Type", "application/json; charset=utf-8")
res.Write(data)
}
@ -194,7 +195,7 @@ func (me *api) robot_connections(name string, res http.ResponseWriter, req *http
}
func (me *api) robot_connection(robot string, connection string, res http.ResponseWriter, req *http.Request) {
data, _ := json.Marshal(me.formatJsonConnection(me.master.FindRobotConnection(robot, connection)))
data, _ := json.Marshal(me.formatJsonConnection(me.master.FindRobot(robot).GetConnection(connection)))
res.Header().Set("Content-Type", "application/json; charset=utf-8")
res.Write(data)
}
@ -224,7 +225,11 @@ func (a *api) formatJsonDevice(device *device) *jsonDevice {
jsonDevice := new(jsonDevice)
jsonDevice.Name = device.Name
jsonDevice.Driver = device.Type
jsonDevice.Connection = a.formatJsonConnection(a.master.FindRobotConnection(device.Robot.Name, FieldByNamePtr(FieldByNamePtr(device.Driver, "Adaptor").Interface().(AdaptorInterface), "Name").Interface().(string)))
jsonDevice.Connection = a.formatJsonConnection(
a.master.FindRobot(device.Robot.Name).
GetConnection(FieldByNamePtr(FieldByNamePtr(device.Driver, "Adaptor").
Interface().(AdaptorInterface), "Name").
Interface().(string)))
jsonDevice.Commands = FieldByNamePtr(device.Driver, "Commands").Interface().([]string)
return jsonDevice
}
@ -233,7 +238,7 @@ func (a *api) executeCommand(robotname string, devicename string, commandname st
data, _ := ioutil.ReadAll(req.Body)
var body map[string]interface{}
json.Unmarshal(data, &body)
robot := a.master.FindRobotDevice(robotname, devicename)
robot := a.master.FindRobot(robotname).GetDevice(devicename)
commands := robot.Commands().([]string)
for command := range commands {
if commands[command] == commandname {

21
api_convention.go Normal file
View File

@ -0,0 +1,21 @@
package gobot
type jsonRobot struct {
Name string `json:"name"`
Commands []string `json:"commands"`
Connections []*jsonConnection `json:"connections"`
Devices []*jsonDevice `json:"devices"`
}
type jsonDevice struct {
Name string `json:"name"`
Driver string `json:"driver"`
Connection *jsonConnection `json:"connection"`
Commands []string `json:"commands"`
}
type jsonConnection struct {
Name string `json:"name"`
Port string `json:"port"`
Adaptor string `json:"adaptor"`
}

9
doc.go Normal file
View File

@ -0,0 +1,9 @@
package gobot
/*
overall doc for my package
*/

View File

@ -10,39 +10,42 @@ type Master struct {
Robots []*Robot
NumCPU int
Api *api
trap func(chan os.Signal)
}
func GobotMaster() *Master {
m := new(Master)
m.NumCPU = runtime.NumCPU()
return m
}
var trap = func(c chan os.Signal) {
signal.Notify(c, os.Interrupt)
// used to be GobotMaster()
func NewMaster() *Master {
return &Master{
NumCPU: runtime.NumCPU(),
trap: func(c chan os.Signal) {
signal.Notify(c, os.Interrupt)
},
}
}
func (m *Master) Start() {
// this changes the amount of cores used by the program
// to match the amount of CPUs set on master.
runtime.GOMAXPROCS(m.NumCPU)
if m.Api != nil {
m.Api.startApi()
m.Api.start()
}
for s := range m.Robots {
m.Robots[s].startRobot()
for _, r := range m.Robots {
r.startRobot()
}
var c = make(chan os.Signal, 1)
trap(c)
m.trap(c)
for _ = range c {
for r := range m.Robots {
m.Robots[r].haltDevices()
m.Robots[r].finalizeConnections()
}
break
// waiting on something coming on the channel
_ = <-c
for _, r := range m.Robots {
r.haltDevices()
r.finalizeConnections()
}
}
func (m *Master) FindRobot(name string) *Robot {
@ -53,19 +56,3 @@ func (m *Master) FindRobot(name string) *Robot {
}
return nil
}
func (m *Master) FindRobotDevice(name string, device string) *device {
robot := m.FindRobot(name)
if robot != nil {
return robot.GetDevice(device)
}
return nil
}
func (m *Master) FindRobotConnection(name string, connection string) *connection {
robot := m.FindRobot(name)
if robot != nil {
return robot.GetConnection(connection)
}
return nil
}

View File

@ -1,9 +1,9 @@
package gobot
import (
"os"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"os"
)
var _ = Describe("Master", func() {
@ -12,16 +12,16 @@ var _ = Describe("Master", func() {
)
BeforeEach(func() {
myMaster = GobotMaster()
myMaster = NewMaster()
myMaster.trap = func(c chan os.Signal) {
c <- os.Interrupt
}
myMaster.Robots = []*Robot{
newTestRobot("Robot 1"),
newTestRobot("Robot 2"),
newTestRobot("Robot 3"),
}
startApi = func(m *api) {}
trap = func(c chan os.Signal) {
c <- os.Interrupt
}
myMaster.Start()
})

View File

@ -19,7 +19,7 @@ type Robot struct {
}
func (r *Robot) Start() {
m := GobotMaster()
m := NewMaster()
m.Robots = []*Robot{r}
m.Start()
}
@ -126,6 +126,9 @@ func (r *Robot) GetDevices() []*device {
}
func (r *Robot) GetDevice(name string) *device {
if r == nil {
return nil
}
for _, device := range r.devices {
if device.Name == name {
return device
@ -139,6 +142,9 @@ func (r *Robot) GetConnections() []*connection {
}
func (r *Robot) GetConnection(name string) *connection {
if r == nil {
return nil
}
for _, connection := range r.connections {
if connection.Name == name {
return connection