<commit_before>// gcvis is a tool to assist you visualising the operation of
// the go runtime garbage collector.
//
// usage:
//
//     gcvis program [arguments]...
package main

import (
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"strings"

	"github.com/pkg/browser"

	"golang.org/x/crypto/ssh/terminal"
)

var iface = flag.String("i", "127.0.0.1", "specify interface to use. defaults to 127.0.0.1.")
var port = flag.String("p", "0", "specify port to use.")
var openBrowser = flag.Bool("o", true, "automatically open browser")

func main() {
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage of %s: command <args>...\n", os.Args[0])
		flag.PrintDefaults()
	}

	var pipeRead io.ReadCloser
	var subcommand *SubCommand

	flag.Parse()
	if len(flag.Args()) < 1 {
		if terminal.IsTerminal(int(os.Stdin.Fd())) {
			flag.Usage()
			return
		} else {
			pipeRead = os.Stdin
		}
	} else {
		subcommand = NewSubCommand(flag.Args())
		pipeRead = subcommand.PipeRead
		go subcommand.Run()
	}

	parser := NewParser(pipeRead)
	gcvisGraph := NewGraph(strings.Join(flag.Args(), " "), GCVIS_TMPL)
	server := NewHttpServer(*iface, *port, &gcvisGraph)

	go parser.Run()
	go server.Start()

	url := server.Url()

	if *openBrowser {
		log.Printf("opening browser window, if this fails, navigate to %s", url)
		browser.OpenURL(url)
	} else {
		log.Printf("server started on %s", url)
	}

	for {
		select {
		case gcTrace := <-parser.GcChan:
			gcvisGraph.AddGCTraceGraphPoint(gcTrace)
		case scvgTrace := <-parser.ScvgChan:
			gcvisGraph.AddScavengerGraphPoint(scvgTrace)
		case output := <-parser.NoMatchChan:
			fmt.Fprintln(os.Stderr, output)
		case <-parser.done:
			if parser.Err != nil {
				fmt.Fprintf(os.Stderr, parser.Err.Error())
				os.Exit(1)
			}

			os.Exit(0)
		}
	}

	if subcommand != nil && subcommand.Err() != nil {
		fmt.Fprintf(os.Stderr, subcommand.Err().Error())
		os.Exit(1)
	}

	os.Exit(0)
}
<commit_msg>gcvis/main.go<commit_after>// gcvis is a tool to assist you visualising the operation of
// the go runtime garbage collector.
//
// usage:
//
//     gcvis program [arguments]...
package main

import (
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"strings"

	"github.com/pkg/browser"

	"golang.org/x/crypto/ssh/terminal"
)

var iface = flag.String("i", "127.0.0.1", "specify interface to use. defaults to 127.0.0.1.")
var port = flag.String("p", "0", "specify port to use.")
var openBrowser = flag.Bool("o", true, "automatically open browser")

func main() {
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage of %s: command <args>...\n", os.Args[0])
		flag.PrintDefaults()
	}

	var pipeRead io.ReadCloser
	var subcommand *SubCommand

	flag.Parse()
	if len(flag.Args()) < 1 {
		if terminal.IsTerminal(int(os.Stdin.Fd())) {
			flag.Usage()
			return
		} else {
			pipeRead = os.Stdin
		}
	} else {
		subcommand = NewSubCommand(flag.Args())
		pipeRead = subcommand.PipeRead
		go subcommand.Run()
	}

	parser := NewParser(pipeRead)

	title := strings.Join(flag.Args(), " ")
	if len(title) == 0 {
		title = fmt.Sprintf("%s:%s", *iface, *port)
	}

	gcvisGraph := NewGraph(title, GCVIS_TMPL)
	server := NewHttpServer(*iface, *port, &gcvisGraph)

	go parser.Run()
	go server.Start()

	url := server.Url()

	if *openBrowser {
		log.Printf("opening browser window, if this fails, navigate to %s", url)
		browser.OpenURL(url)
	} else {
		log.Printf("server started on %s", url)
	}

	for {
		select {
		case gcTrace := <-parser.GcChan:
			gcvisGraph.AddGCTraceGraphPoint(gcTrace)
		case scvgTrace := <-parser.ScvgChan:
			gcvisGraph.AddScavengerGraphPoint(scvgTrace)
		case output := <-parser.NoMatchChan:
			fmt.Fprintln(os.Stderr, output)
		case <-parser.done:
			if parser.Err != nil {
				fmt.Fprintf(os.Stderr, parser.Err.Error())
				os.Exit(1)
			}

			os.Exit(0)
		}
	}

	if subcommand != nil && subcommand.Err() != nil {
		fmt.Fprintf(os.Stderr, subcommand.Err().Error())
		os.Exit(1)
	}

	os.Exit(0)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	_ "net/http/pprof"
	"os"

	"github.com/Financial-Times/base-ft-rw-app-go/baseftrwapp"
	"github.com/Financial-Times/go-fthealth/v1a"
	"github.com/Financial-Times/memberships-rw-neo4j/memberships"
	"github.com/Financial-Times/neo-utils-go/neoutils"
	log "github.com/Sirupsen/logrus"
	"github.com/jawher/mow.cli"
	"github.com/jmcvetta/neoism"
)

func main() {
	log.Println("Application starting with args %s", os.Args)
	app := cli.App("memberships-rw-neo4j", "A RESTful API for managing Memberships in neo4j")
	neoURL := app.StringOpt("neo-url", "http://localhost:7474/db/data", "neo4j endpoint URL")
	port := app.IntOpt("port", 8080, "Port to listen on")
	env := app.StringOpt("env", "local", "environment this app is running in")
	batchSize := app.IntOpt("batchSize", 1024, "Maximum number of statements to execute per batch")
	graphiteTCPAddress := app.StringOpt("graphiteTCPAddress", "",
		"Graphite TCP address, e.g. graphite.ft.com:2003. Leave as default if you do NOT want to output to graphite (e.g. if running locally)")
	graphitePrefix := app.StringOpt("graphitePrefix", "",
		"Prefix to use. Should start with content, include the environment, and the host name. e.g. content.test.memberships.rw.neo4j.ftaps58938-law1a-eu-t")
	logMetrics := app.BoolOpt("logMetrics", false, "Whether to log metrics. Set to true if running locally and you want metrics output")

	app.Action = func() {
		db, err := neoism.Connect(*neoURL)
		if err != nil {
			log.Errorf("Could not connect to neo4j, error=[%s]\n", err)
		}

		batchRunner := neoutils.NewBatchCypherRunner(neoutils.StringerDb{db}, *batchSize)
		membershipsDriver := memberships.NewCypherDriver(batchRunner, db)
		membershipsDriver.Initialise()

		baseftrwapp.OutputMetricsIfRequired(*graphiteTCPAddress, *graphitePrefix, *logMetrics)

		engs := map[string]baseftrwapp.Service{
			"memberships": membershipsDriver,
		}

		var checks []v1a.Check
		for _, e := range engs {
			checks = append(checks, makeCheck(e, batchRunner))
		}

		baseftrwapp.RunServer(engs,
			v1a.Handler("ft-memberships_rw_neo4j ServiceModule", "Writes 'memberships' to Neo4j, usually as part of a bulk upload done on a schedule", checks...),
			*port, "memberships-rw-neo4j", *env)
	}

	app.Run(os.Args)
	log.SetLevel(log.InfoLevel)
	log.Println("Application started with args %s", os.Args)
}

func makeCheck(service baseftrwapp.Service, cr neoutils.CypherRunner) v1a.Check {
	return v1a.Check{
		BusinessImpact:   "Cannot read/write memberships via this writer",
		Name:             "Check connectivity to Neo4j - neoUrl is a parameter in hieradata for this service",
		PanicGuide:       "TODO - write panic guide",
		Severity:         1,
		TechnicalSummary: fmt.Sprintf("Cannot connect to Neo4j instance %s with at least one person loaded in it", cr),
		Checker:          func() (string, error) { return "", service.Check() },
	}
}
<commit_msg>Adding 'MaxIdleConnsPerHost' to neo4j http client config.<commit_after>package main

import (
	"fmt"
	_ "net/http/pprof"
	"os"

	"github.com/Financial-Times/base-ft-rw-app-go/baseftrwapp"
	"github.com/Financial-Times/go-fthealth/v1a"
	"github.com/Financial-Times/memberships-rw-neo4j/memberships"
	"github.com/Financial-Times/neo-utils-go/neoutils"
	log "github.com/Sirupsen/logrus"
	"github.com/jawher/mow.cli"
	"github.com/jmcvetta/neoism"
	"net/http"
)

func main() {
	log.Println("Application starting with args %s", os.Args)
	app := cli.App("memberships-rw-neo4j", "A RESTful API for managing Memberships in neo4j")
	neoURL := app.StringOpt("neo-url", "http://localhost:7474/db/data", "neo4j endpoint URL")
	port := app.IntOpt("port", 8080, "Port to listen on")
	env := app.StringOpt("env", "local", "environment this app is running in")
	batchSize := app.IntOpt("batchSize", 1024, "Maximum number of statements to execute per batch")
	graphiteTCPAddress := app.StringOpt("graphiteTCPAddress", "",
		"Graphite TCP address, e.g. graphite.ft.com:2003. Leave as default if you do NOT want to output to graphite (e.g. if running locally)")
	graphitePrefix := app.StringOpt("graphitePrefix", "",
		"Prefix to use. Should start with content, include the environment, and the host name. e.g. content.test.memberships.rw.neo4j.ftaps58938-law1a-eu-t")
	logMetrics := app.BoolOpt("logMetrics", false, "Whether to log metrics. Set to true if running locally and you want metrics output")

	app.Action = func() {
		db, err := neoism.Connect(*neoURL)
		db.Session.Client = &http.Client{Transport: &http.Transport{MaxIdleConnsPerHost: 100}}
		if err != nil {
			log.Errorf("Could not connect to neo4j, error=[%s]\n", err)
		}

		batchRunner := neoutils.NewBatchCypherRunner(neoutils.StringerDb{db}, *batchSize)
		membershipsDriver := memberships.NewCypherDriver(batchRunner, db)
		membershipsDriver.Initialise()

		baseftrwapp.OutputMetricsIfRequired(*graphiteTCPAddress, *graphitePrefix, *logMetrics)

		engs := map[string]baseftrwapp.Service{
			"memberships": membershipsDriver,
		}

		var checks []v1a.Check
		for _, e := range engs {
			checks = append(checks, makeCheck(e, batchRunner))
		}

		baseftrwapp.RunServer(engs,
			v1a.Handler("ft-memberships_rw_neo4j ServiceModule", "Writes 'memberships' to Neo4j, usually as part of a bulk upload done on a schedule", checks...),
			*port, "memberships-rw-neo4j", *env)
	}

	app.Run(os.Args)
	log.SetLevel(log.InfoLevel)
	log.Println("Application started with args %s", os.Args)
}

func makeCheck(service baseftrwapp.Service, cr neoutils.CypherRunner) v1a.Check {
	return v1a.Check{
		BusinessImpact:   "Cannot read/write memberships via this writer",
		Name:             "Check connectivity to Neo4j - neoUrl is a parameter in hieradata for this service",
		PanicGuide:       "TODO - write panic guide",
		Severity:         1,
		TechnicalSummary: fmt.Sprintf("Cannot connect to Neo4j instance %s with at least one person loaded in it", cr),
		Checker:          func() (string, error) { return "", service.Check() },
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"net/http"
)

func main() {
	http.HandleFunc("/", handler)
	http.ListenAndServe(":8080", nil)
}

func handler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, "Hello, world - updated!")
}
<commit_msg>updated response<commit_after>package main

import (
	"fmt"
	"net/http"
)

func main() {
	http.HandleFunc("/", handler)
	http.ListenAndServe(":8080", nil)
}

func handler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, "Hello, world!")
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"log"
	"os"
	"time"

	"github.com/ninjasphere/go-ninja/api"
	nlog "github.com/ninjasphere/go-ninja/logger"
	"github.com/ninjasphere/go-ninja/support"
	"github.com/ninjasphere/sphere-go-led-controller/model"
	"github.com/paypal/gatt"
)

const WirelessNetworkInterface = "wlan0"

// consider the wifi to be invalid after this timeout
const WirelessStaleTimeout = time.Second * 30 // FIXME: INCREASE THIS. a few minutes at least when not in testing.

var firewallHook = flag.Bool("firewall-hook", false, "Sets up the firewall based on configuration options, and nothing else.")
var factoryReset = false

// factoryReset - we can't use anything that requires MQTT in this mode

var logger = nlog.GetLogger("sphere-setup")

func main() {
	// ap0 adhoc/hostap management
	flag.BoolVar(&factoryReset, "factory-reset", false, "Run in factory reset mode.")

	go func() {
		support.WaitUntilSignal()
	}()

	config := LoadConfig("/etc/opt/ninja/setup-assistant.conf")
	apManager := NewAccessPointManager(config)

	flag.Parse()
	if *firewallHook {
		logger.Debugf("Setting ip firewall rules...")
		apManager.SetupFirewall()
		return
	}
	var pairing_ui ConsolePairingUI
	var controlChecker *ControlChecker

	restartHeartbeat := false

	startResetMonitor(func(m *model.ResetMode) {
		if pairing_ui == nil || controlChecker == nil {
			return
		}
		if m.Mode == "none" {
			if restartHeartbeat {
				// only restart the heartbeat if we stopped it previously
				controlChecker.StartHeartbeat()
			}
		} else {
			restartHeartbeat = controlChecker.StopHeartbeat()
			pairing_ui.DisplayResetMode(m)
		}
	})

	apManager.WriteAPConfig()
	if config.Wireless_Host.Always_Active {
		apManager.StartHostAP()
	} else {
		apManager.StopHostAP()
	}

	// wlan0 client management
	wifi_manager, err := NewWifiManager(WirelessNetworkInterface)
	if err != nil {
		log.Fatal("Could not setup manager for wlan0, does the interface exist?: %v", err)
	}
	defer wifi_manager.Cleanup()

	// When in reset mode, this will talk to the led matrix directly,
	// otherwise, it will use sphere-go-led-controller via mqtt.
	pairing_ui, err = NewPairingUI()
	if err != nil {
		log.Fatal("Could not setup ninja connection")
	}

	// This name is sent in the BLE advertising packet,
	// and is used by the phone to see that this is a
	// sphere, and if it is in factory reset mode.
	serviceName := "ninjasphere"
	if factoryReset {
		serviceName = "resetsphere"
	}

	srv := &gatt.Server{
		Name: serviceName,
		Connect: func(c gatt.Conn) {
			logger.Infof("BLE Connect")
			pairing_ui.DisplayIcon("ble-connected.gif")
		},
		Disconnect: func(c gatt.Conn) {
			logger.Infof("BLE Disconnect")
			pairing_ui.DisplayIcon("ble-disconnected.gif")
		},
		StateChange: func(state string) {
			logger.Infof("BLE State Change: %s", state)
		},
	}

	var conn *ninja.Connection

	if !factoryReset {

		conn, err = ninja.Connect("sphere-setup-assistant-updates")

		if err != nil {
			logger.FatalErrorf(err, "Failed to connect to mqtt")
		}
	}

	// start by registering the RPC functions that will be accessible
	// once the client has authenticated
	// We pass in the ble server so that we can close the connection once the updates are installed
	// (THIS SHOULD HAPPEN OVER WIFI INSTEAD!)
	rpc_router := GetSetupRPCRouter(conn, wifi_manager, srv, pairing_ui)

	StartHTTPServer(conn, wifi_manager, pairing_ui)

	auth_handler := new(OneTimeAuthHandler)
	auth_handler.Init("spheramid")

	controlChecker = NewControlChecker(pairing_ui)

	RegisterSecuredRPCService(srv, rpc_router, auth_handler, pairing_ui)

	// Start the server
	//log.Println("Starting setup assistant...");
	//log.Fatal(srv.AdvertiseAndServe())

	states := wifi_manager.WatchState()

	//wifi_manager.WifiConfigured()

	var wireless_stale *time.Timer

	is_serving_pairer := false

	// start by forcing the state to Disconnected.
	// reloading the configuration in wpa_supplicant will also force this,
	// but we need to do it here in case we are already disconnected
	states <- WifiStateDisconnected
	wifi_manager.Controller.ReloadConfiguration()

	handleBadWireless := func() {
		logger.Warningf("Wireless is stale! Invalid SSID, router down, or not in range.")

		if !is_serving_pairer {
			is_serving_pairer = true
			logger.Infof("Launching BLE pairing assistant...")
			go func() {
				err := srv.AdvertiseAndServe()
				if err != nil {
					logger.Errorf("failure to advertise and serve: ", err)
				}
			}()
			// and if the hostap isn't normally active, make it active
			if !config.Wireless_Host.Always_Active {
				logger.Infof("Launching AdHoc pairing assistant...")
				apManager.StartHostAP()
			}
		}
	}

	wifi_configured, _ := wifi_manager.WifiConfigured()
	if !wifi_configured {
		// when wireless isn't configured at all, automatically start doing this, don't wait for staleness
		handleBadWireless()
	}

	if config.Wireless_Host.Enables_Control {
		// the wireless AP causes control to be enabled, so we just start the heartbeat immediately
		controlChecker.StartHeartbeat()
	}

	for {
		state := <-states
		logger.Infof("State: %v", state)

		switch state {
		case WifiStateConnected:
			if wireless_stale != nil {
				wireless_stale.Stop()
			}
			wireless_stale = nil
			logger.Infof("Connected and attempting to get IP.")

			/*if !config.Wireless_Host.Enables_Control {
				// if the wireless AP mode hasn't already enabled normal control, then enable it now that wifi works
				controlChecker.StartHeartbeat()
			}*/

			if is_serving_pairer {
				is_serving_pairer = false

				// We need to keep the server open for now, as we are sending update progress to it, and accepting
				// led drawing messages. Later, this will be over wifi and we can close it here.
				//srv.Close()

				// and if the hostap isn't normally active, turn it off again
				if !config.Wireless_Host.Always_Active {
					logger.Infof("Terminating AdHoc pairing assistant.")
					apManager.StopHostAP()
				}
			}
			if factoryReset {
				logger.Infof("Network connected. Quitting.")
				os.Exit(0)
			}

		case WifiStateDisconnected:
			if wireless_stale == nil {
				wireless_stale = time.AfterFunc(WirelessStaleTimeout, handleBadWireless)
			}

		case WifiStateInvalidKey:
			if wireless_stale == nil {
				wireless_stale = time.AfterFunc(WirelessStaleTimeout, handleBadWireless)
			}
			wifi_configured, _ = wifi_manager.WifiConfigured()
			if wifi_configured {
				// not stale, we actually know the key is wrong
				// FIXME: report back to the user! for now we're just going to let staleness timeout
				/*if wireless_stale != nil {
					wireless_stale.Stop()
				}
				wireless_stale = nil*/

				logger.Warningf("Wireless key is invalid!")
			}
		}
	}
}
<commit_msg>Fail noisily if hci-ble isn't there.<commit_after>package main

import (
	"flag"
	"log"
	"os"
	"time"

	"github.com/ninjasphere/go-ninja/api"
	nlog "github.com/ninjasphere/go-ninja/logger"
	"github.com/ninjasphere/go-ninja/support"
	"github.com/ninjasphere/sphere-go-led-controller/model"
	"github.com/paypal/gatt"
)

const WirelessNetworkInterface = "wlan0"

// consider the wifi to be invalid after this timeout
const WirelessStaleTimeout = time.Second * 30 // FIXME: INCREASE THIS. a few minutes at least when not in testing.

var firewallHook = flag.Bool("firewall-hook", false, "Sets up the firewall based on configuration options, and nothing else.")
var factoryReset = false

// factoryReset - we can't use anything that requires MQTT in this mode

var logger = nlog.GetLogger("sphere-setup")

func main() {
	// ap0 adhoc/hostap management
	flag.BoolVar(&factoryReset, "factory-reset", false, "Run in factory reset mode.")

	go func() {
		support.WaitUntilSignal()
	}()

	config := LoadConfig("/etc/opt/ninja/setup-assistant.conf")
	apManager := NewAccessPointManager(config)

	flag.Parse()
	if *firewallHook {
		logger.Debugf("Setting ip firewall rules...")
		apManager.SetupFirewall()
		return
	}
	var pairing_ui ConsolePairingUI
	var controlChecker *ControlChecker

	restartHeartbeat := false

	startResetMonitor(func(m *model.ResetMode) {
		if pairing_ui == nil || controlChecker == nil {
			return
		}
		if m.Mode == "none" {
			if restartHeartbeat {
				// only restart the heartbeat if we stopped it previously
				controlChecker.StartHeartbeat()
			}
		} else {
			restartHeartbeat = controlChecker.StopHeartbeat()
			pairing_ui.DisplayResetMode(m)
		}
	})

	apManager.WriteAPConfig()
	if config.Wireless_Host.Always_Active {
		apManager.StartHostAP()
	} else {
		apManager.StopHostAP()
	}

	// wlan0 client management
	wifi_manager, err := NewWifiManager(WirelessNetworkInterface)
	if err != nil {
		log.Fatal("Could not setup manager for wlan0, does the interface exist?: %v", err)
	}
	defer wifi_manager.Cleanup()

	// When in reset mode, this will talk to the led matrix directly,
	// otherwise, it will use sphere-go-led-controller via mqtt.
	pairing_ui, err = NewPairingUI()
	if err != nil {
		log.Fatal("Could not setup ninja connection")
	}

	// This name is sent in the BLE advertising packet,
	// and is used by the phone to see that this is a
	// sphere, and if it is in factory reset mode.
	serviceName := "ninjasphere"
	if factoryReset {
		serviceName = "resetsphere"
	}

	srv := &gatt.Server{
		Name: serviceName,
		Connect: func(c gatt.Conn) {
			logger.Infof("BLE Connect")
			pairing_ui.DisplayIcon("ble-connected.gif")
		},
		Disconnect: func(c gatt.Conn) {
			logger.Infof("BLE Disconnect")
			pairing_ui.DisplayIcon("ble-disconnected.gif")
		},
		StateChange: func(state string) {
			logger.Infof("BLE State Change: %s", state)
		},
	}

	var conn *ninja.Connection

	if !factoryReset {

		conn, err = ninja.Connect("sphere-setup-assistant-updates")

		if err != nil {
			logger.FatalErrorf(err, "Failed to connect to mqtt")
		}
	}

	// start by registering the RPC functions that will be accessible
	// once the client has authenticated
	// We pass in the ble server so that we can close the connection once the updates are installed
	// (THIS SHOULD HAPPEN OVER WIFI INSTEAD!)
	rpc_router := GetSetupRPCRouter(conn, wifi_manager, srv, pairing_ui)

	StartHTTPServer(conn, wifi_manager, pairing_ui)

	auth_handler := new(OneTimeAuthHandler)
	auth_handler.Init("spheramid")

	controlChecker = NewControlChecker(pairing_ui)

	RegisterSecuredRPCService(srv, rpc_router, auth_handler, pairing_ui)

	// Start the server
	//log.Println("Starting setup assistant...");
	//log.Fatal(srv.AdvertiseAndServe())

	states := wifi_manager.WatchState()

	//wifi_manager.WifiConfigured()

	var wireless_stale *time.Timer

	is_serving_pairer := false

	// start by forcing the state to Disconnected.
	// reloading the configuration in wpa_supplicant will also force this,
	// but we need to do it here in case we are already disconnected
	states <- WifiStateDisconnected
	wifi_manager.Controller.ReloadConfiguration()

	handleBadWireless := func() {
		logger.Warningf("Wireless is stale! Invalid SSID, router down, or not in range.")

		if !is_serving_pairer {
			is_serving_pairer = true
			logger.Infof("Launching BLE pairing assistant...")
			go func() {
				err := srv.AdvertiseAndServe()
				if err != nil {
					logger.Fatalf("failure to advertise and serve: %v", err)
				}
			}()
			// and if the hostap isn't normally active, make it active
			if !config.Wireless_Host.Always_Active {
				logger.Infof("Launching AdHoc pairing assistant...")
				apManager.StartHostAP()
			}
		}
	}

	wifi_configured, _ := wifi_manager.WifiConfigured()
	if !wifi_configured {
		// when wireless isn't configured at all, automatically start doing this, don't wait for staleness
		handleBadWireless()
	}

	if config.Wireless_Host.Enables_Control {
		// the wireless AP causes control to be enabled, so we just start the heartbeat immediately
		controlChecker.StartHeartbeat()
	}

	for {
		state := <-states
		logger.Infof("State: %v", state)

		switch state {
		case WifiStateConnected:
			if wireless_stale != nil {
				wireless_stale.Stop()
			}
			wireless_stale = nil
			logger.Infof("Connected and attempting to get IP.")

			/*if !config.Wireless_Host.Enables_Control {
				// if the wireless AP mode hasn't already enabled normal control, then enable it now that wifi works
				controlChecker.StartHeartbeat()
			}*/

			if is_serving_pairer {
				is_serving_pairer = false

				// We need to keep the server open for now, as we are sending update progress to it, and accepting
				// led drawing messages. Later, this will be over wifi and we can close it here.
				//srv.Close()

				// and if the hostap isn't normally active, turn it off again
				if !config.Wireless_Host.Always_Active {
					logger.Infof("Terminating AdHoc pairing assistant.")
					apManager.StopHostAP()
				}
			}
			if factoryReset {
				logger.Infof("Network connected. Quitting.")
				os.Exit(0)
			}

		case WifiStateDisconnected:
			if wireless_stale == nil {
				wireless_stale = time.AfterFunc(WirelessStaleTimeout, handleBadWireless)
			}

		case WifiStateInvalidKey:
			if wireless_stale == nil {
				wireless_stale = time.AfterFunc(WirelessStaleTimeout, handleBadWireless)
			}
			wifi_configured, _ = wifi_manager.WifiConfigured()
			if wifi_configured {
				// not stale, we actually know the key is wrong
				// FIXME: report back to the user! for now we're just going to let staleness timeout
				/*if wireless_stale != nil {
					wireless_stale.Stop()
				}
				wireless_stale = nil*/

				logger.Warningf("Wireless key is invalid!")
			}
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/base64"
	"fmt"
	"os"

	"github.com/midnightfreddie/McpeTool/api"
	"github.com/midnightfreddie/McpeTool/world"
	"github.com/urfave/cli"
)

func main() {
	app := cli.NewApp()
	app.Name = "MCPE Tool"
	app.Version = "0.0.0"
	app.Usage = "A utility to access Minecraft Pocket Edition .mcworld exported world files."

	app.Commands = []cli.Command{
		{
			Name:    "api",
			Aliases: []string{"www"},
			Usage:   "Open world and start http API. Hit control-c to exit.",
			Action: func(c *cli.Context) error {
				world, err := world.OpenWorld(c.Args().First())
				if err != nil {
					panic("error")
				}
				defer world.Close()
				err = api.Server(&world)
				if err != nil {
					panic("error")
				}
				return nil
			},
		},
		{
			Name:    "keys",
			Aliases: []string{"k"},
			Usage:   "Lists all keys in the database in base64 format. Be sure to include the path to the world folder, e.g. 'McpeTool keys path/to/world'",
			Action: func(c *cli.Context) error {
				world, err := world.OpenWorld(c.Args().First())
				if err != nil {
					return err
				}
				defer world.Close()
				keys, err := world.GetKeys()
				if err != nil {
					return err
				}
				for i := 0; i < len(keys); i++ {
					fmt.Println(base64.StdEncoding.EncodeToString(keys[i]))
				}
				return nil
			},
		},
		{
			Name:  "get",
			Usage: "Retruns the value of a key. Both key and value are in base64 format. e.g. 'McpeTool get path/to/world AAAAAAAAAAAw' for terrain chunk 0,0 or 'McpeTool get path/to/world fmxvY2FsX3BsYXllcg==' for ~local_player player data",
			Action: func(c *cli.Context) error {
				world, err := world.OpenWorld(c.Args().First())
				if err != nil {
					return err
				}
				defer world.Close()
				key, err := base64.StdEncoding.DecodeString(c.Args().Get(1))
				if err != nil {
					return err
				}
				value, err := world.Get(key)
				if err != nil {
					return err
				}
				fmt.Println(base64.StdEncoding.EncodeToString(value))
				return nil
			},
		},
		{
			Name:  "delete",
			Usage: "Deletes a key and its value. The key is in base64 format. e.g. 'McpeTool delete path/to/world AAAAAAAAAAAw' to delete terrain chunk 0,0 or 'McpeTool delete path/to/world fmxvY2FsX3BsYXllcg==' to delete ~local_player player data",
			Action: func(c *cli.Context) error {
				world, err := world.OpenWorld(c.Args().First())
				if err != nil {
					return err
				}
				defer world.Close()
				key, err := base64.StdEncoding.DecodeString(c.Args().Get(1))
				if err != nil {
					return err
				}
				err = world.Delete(key)
				if err != nil {
					return err
				}
				return nil
			},
		},
		{
			Name:    "develop",
			Aliases: []string{"dev"},
			Usage:   "Random thing the dev is working on",
			Action: func(c *cli.Context) error {
				world, err := world.OpenWorld(c.Args().First())
				if err != nil {
					return err
				}
				defer world.Close()
				keys, err := world.GetKeys()
				if err != nil {
					return err
				}
				fmt.Printf("%v\n", keys)
				fmt.Println(world.FilePath())
				return nil
			},
		},
	}

	app.Run(os.Args)
}
<commit_msg>Changed cli commands to use hex for keys<commit_after>package main

import (
	"encoding/base64"
	"encoding/hex"
	"fmt"
	"os"

	"github.com/midnightfreddie/McpeTool/api"
	"github.com/midnightfreddie/McpeTool/world"
	"github.com/urfave/cli"
)

func main() {
	app := cli.NewApp()
	app.Name = "MCPE Tool"
	app.Version = "0.0.0"
	app.Usage = "A utility to access Minecraft Pocket Edition .mcworld exported world files."

	app.Commands = []cli.Command{
		{
			Name:    "api",
			Aliases: []string{"www"},
			Usage:   "Open world and start http API. Hit control-c to exit.",
			Action: func(c *cli.Context) error {
				world, err := world.OpenWorld(c.Args().First())
				if err != nil {
					panic("error")
				}
				defer world.Close()
				err = api.Server(&world)
				if err != nil {
					panic("error")
				}
				return nil
			},
		},
		{
			Name:    "keys",
			Aliases: []string{"k"},
			Usage:   "Lists all keys in the database in hex format. Be sure to include the path to the world folder, e.g. 'McpeTool keys path/to/world'",
			Action: func(c *cli.Context) error {
				world, err := world.OpenWorld(c.Args().First())
				if err != nil {
					return err
				}
				defer world.Close()
				keys, err := world.GetKeys()
				if err != nil {
					return err
				}
				for i := 0; i < len(keys); i++ {
					fmt.Println(hex.EncodeToString(keys[i]))
				}
				return nil
			},
		},
		{
			Name:  "get",
			Usage: "Retruns the value of a key. Key is in hex format and value is in base64 format. e.g. 'McpeTool get path/to/world 000000000000000030' for terrain chunk 0,0 or 'McpeTool get path/to/world 7e6c6f63616c5f706c61796572' for ~local_player player data",
			Action: func(c *cli.Context) error {
				world, err := world.OpenWorld(c.Args().First())
				if err != nil {
					return err
				}
				defer world.Close()
				key, err := hex.DecodeString(c.Args().Get(1))
				if err != nil {
					return err
				}
				value, err := world.Get(key)
				if err != nil {
					return err
				}
				fmt.Println(base64.StdEncoding.EncodeToString(value))
				return nil
			},
		},
		{
			Name:  "delete",
			Usage: "Deletes a key and its value. The key is in base64 format. e.g. 'McpeTool delete path/to/world 000000000000000030' to delete terrain chunk 0,0 or 'McpeTool delete path/to/world 7e6c6f63616c5f706c61796572' to delete ~local_player player data",
			Action: func(c *cli.Context) error {
				world, err := world.OpenWorld(c.Args().First())
				if err != nil {
					return err
				}
				defer world.Close()
				key, err := hex.DecodeString(c.Args().Get(1))
				if err != nil {
					return err
				}
				err = world.Delete(key)
				if err != nil {
					return err
				}
				return nil
			},
		},
		{
			Name:    "develop",
			Aliases: []string{"dev"},
			Usage:   "Random thing the dev is working on",
			Action: func(c *cli.Context) error {
				world, err := world.OpenWorld(c.Args().First())
				if err != nil {
					return err
				}
				defer world.Close()
				keys, err := world.GetKeys()
				if err != nil {
					return err
				}
				fmt.Printf("%v\n", keys)
				fmt.Println(world.FilePath())
				return nil
			},
		},
	}

	app.Run(os.Args)
}
<|endoftext|>


<commit_before>package main

import (
	"log"
	"net/http"
	"os"
	"runtime"
	"sync"
	"time"

	"github.com/couchbaselabs/gateload/api"
	"github.com/couchbaselabs/gateload/workload"
)

const (
	AUTH_TYPE_SESSION = "session"
	AUTH_TYPE_BASIC   = "basic"
)

func main() {

	if os.Getenv("GOMAXPROCS") == "" {
		log.Printf("Setting GOMAXPROCS to %v", runtime.NumCPU())
		runtime.GOMAXPROCS(runtime.NumCPU())
	} else {
		log.Printf("GOMAXPROCS is set at %v", os.Getenv("GOMAXPROCS"))
	}

	// start up an http server, just to serve up expvars
	go http.ListenAndServe(":9876", nil)

	var config workload.Config
	workload.ReadConfig(&config)

	admin := api.SyncGatewayClient{}
	admin.Init(
		config.Hostname,
		config.Database,
		config.Port,
		config.AdminPort,
		config.LogRequests,
	)
	if !admin.Valid() {
		log.Fatalf("unable to connect to sync_gateway, check the hostname and database")
	}

	pendingUsers := make(chan *workload.User)
	users := make([]*workload.User, config.NumPullers+config.NumPushers)

	// start a routine to place pending users into array
	go func() {
		for pendingUser := range pendingUsers {

			// users = append(users, pendingUser)
			users[pendingUser.SeqId-config.UserOffset] = pendingUser
		}
	}()

	rampUpDelay := config.RampUpIntervalMs / (config.NumPullers + config.NumPushers)

	// use a fixed number of workers to create the users/sessions
	userIterator := workload.UserIterator(
		config.NumPullers,
		config.NumPushers,
		config.UserOffset,
		config.ChannelActiveUsers,
		config.ChannelConcurrentUsers,
		config.MinUserOffTimeMs,
		config.MaxUserOffTimeMs,
		rampUpDelay,
		config.RunTimeMs,
	)
	adminWg := sync.WaitGroup{}
	worker := func() {
		defer adminWg.Done()
		for user := range userIterator {
			createSession(&admin, user, config)
			pendingUsers <- user
		}
	}

	for i := 0; i < 200; i++ {
		adminWg.Add(1)
		go worker()
	}

	// wait for all the workers to finish
	adminWg.Wait()
	// close the pending users channel to free that routine
	close(pendingUsers)

	numChannels := (config.NumPullers + config.NumPushers) / config.ChannelActiveUsers
	channelRampUpDelayMs := time.Duration(config.RampUpIntervalMs/numChannels) * time.Millisecond

	wg := sync.WaitGroup{}
	channel := ""
	for _, user := range users {
		nextChannel := user.Channel
		if channel != nextChannel {
			if channel != "" {
				time.Sleep(channelRampUpDelayMs)
			}
			channel = nextChannel
		}
		wg := sync.WaitGroup{}
		go runUser(user, config, &wg)
		wg.Add(1)
	}

	if config.RunTimeMs > 0 {
		time.Sleep(time.Duration(config.RunTimeMs-config.RampUpIntervalMs) * time.Millisecond)
		log.Println("Shutting down clients")
	} else {
		wg.Wait()
	}
}

func createSession(admin *api.SyncGatewayClient, user *workload.User, config workload.Config) {

	userMeta := api.UserAuth{
		Name:          user.Name,
		Password:      config.Password,
		AdminChannels: []string{user.Channel},
	}
	admin.AddUser(user.Name, userMeta, user.Type)

	if config.AuthType == AUTH_TYPE_SESSION {

		session := api.Session{Name: user.Name, TTL: 2592000} // 1 month
		log.Printf("====== Creating new session for %s (%s)", user.Type, user.Name)
		user.Cookie = admin.CreateSession(user.Name, session)
		log.Printf("====== Done Creating new session for %s (%s)", user.Type, user.Name)

	}

}

func runUser(user *workload.User, config workload.Config, wg *sync.WaitGroup) {
	c := api.SyncGatewayClient{}
	c.Init(
		config.Hostname,
		config.Database,
		config.Port,
		config.AdminPort,
		config.LogRequests,
	)
	if config.AuthType == AUTH_TYPE_SESSION {
		c.AddCookie(&user.Cookie)
	} else {
		c.AddUsername(user.Name)
		c.AddPassword(config.Password)
	}

	log.Printf("Starting new %s (%s)", user.Type, user.Name)
	if user.Type == "pusher" {
		go workload.RunNewPusher(
			user.Schedule,
			user.Name,
			&c,
			user.Channel,
			config.DocSize,
			config.SendAttachment,
			config.DocSizeDistribution,
			user.SeqId,
			config.SleepTimeMs,
			wg,
			config.AddDocToTargetUser,
		)
	} else {
		go workload.RunNewPuller(
			user.Schedule,
			&c,
			user.Channel,
			user.Name,
			config.FeedType,
			wg,
		)
	}
	log.Printf("------ Done Starting new %s (%s)", user.Type, user.Name)

}
<commit_msg>add writeExpvarsToFile()<commit_after>package main

import (
	"io"
	"log"
	"net/http"
	"os"
	"runtime"
	"sync"
	"time"

	"github.com/couchbaselabs/gateload/api"
	"github.com/couchbaselabs/gateload/workload"
)

const (
	AUTH_TYPE_SESSION = "session"
	AUTH_TYPE_BASIC   = "basic"
)

func main() {

	if os.Getenv("GOMAXPROCS") == "" {
		log.Printf("Setting GOMAXPROCS to %v", runtime.NumCPU())
		runtime.GOMAXPROCS(runtime.NumCPU())
	} else {
		log.Printf("GOMAXPROCS is set at %v", os.Getenv("GOMAXPROCS"))
	}

	// start up an http server, just to serve up expvars
	go http.ListenAndServe(":9876", nil)

	var config workload.Config
	workload.ReadConfig(&config)

	admin := api.SyncGatewayClient{}
	admin.Init(
		config.Hostname,
		config.Database,
		config.Port,
		config.AdminPort,
		config.LogRequests,
	)
	if !admin.Valid() {
		log.Fatalf("unable to connect to sync_gateway, check the hostname and database")
	}

	pendingUsers := make(chan *workload.User)
	users := make([]*workload.User, config.NumPullers+config.NumPushers)

	// start a routine to place pending users into array
	go func() {
		for pendingUser := range pendingUsers {

			// users = append(users, pendingUser)
			users[pendingUser.SeqId-config.UserOffset] = pendingUser
		}
	}()

	rampUpDelay := config.RampUpIntervalMs / (config.NumPullers + config.NumPushers)

	// use a fixed number of workers to create the users/sessions
	userIterator := workload.UserIterator(
		config.NumPullers,
		config.NumPushers,
		config.UserOffset,
		config.ChannelActiveUsers,
		config.ChannelConcurrentUsers,
		config.MinUserOffTimeMs,
		config.MaxUserOffTimeMs,
		rampUpDelay,
		config.RunTimeMs,
	)
	adminWg := sync.WaitGroup{}
	worker := func() {
		defer adminWg.Done()
		for user := range userIterator {
			createSession(&admin, user, config)
			pendingUsers <- user
		}
	}

	for i := 0; i < 200; i++ {
		adminWg.Add(1)
		go worker()
	}

	// wait for all the workers to finish
	adminWg.Wait()
	// close the pending users channel to free that routine
	close(pendingUsers)

	numChannels := (config.NumPullers + config.NumPushers) / config.ChannelActiveUsers
	channelRampUpDelayMs := time.Duration(config.RampUpIntervalMs/numChannels) * time.Millisecond

	wg := sync.WaitGroup{}
	channel := ""
	for _, user := range users {
		nextChannel := user.Channel
		if channel != nextChannel {
			if channel != "" {
				time.Sleep(channelRampUpDelayMs)
			}
			channel = nextChannel
		}
		wg := sync.WaitGroup{}
		go runUser(user, config, &wg)
		wg.Add(1)
	}

	if config.RunTimeMs > 0 {
		time.Sleep(time.Duration(config.RunTimeMs-config.RampUpIntervalMs) * time.Millisecond)
		log.Println("Shutting down clients")
	} else {
		wg.Wait()
	}

	writeExpvarsToFile()

}

func createSession(admin *api.SyncGatewayClient, user *workload.User, config workload.Config) {

	userMeta := api.UserAuth{
		Name:          user.Name,
		Password:      config.Password,
		AdminChannels: []string{user.Channel},
	}
	admin.AddUser(user.Name, userMeta, user.Type)

	if config.AuthType == AUTH_TYPE_SESSION {

		session := api.Session{Name: user.Name, TTL: 2592000} // 1 month
		log.Printf("====== Creating new session for %s (%s)", user.Type, user.Name)
		user.Cookie = admin.CreateSession(user.Name, session)
		log.Printf("====== Done Creating new session for %s (%s)", user.Type, user.Name)

	}

}

func runUser(user *workload.User, config workload.Config, wg *sync.WaitGroup) {
	c := api.SyncGatewayClient{}
	c.Init(
		config.Hostname,
		config.Database,
		config.Port,
		config.AdminPort,
		config.LogRequests,
	)
	if config.AuthType == AUTH_TYPE_SESSION {
		c.AddCookie(&user.Cookie)
	} else {
		c.AddUsername(user.Name)
		c.AddPassword(config.Password)
	}

	log.Printf("Starting new %s (%s)", user.Type, user.Name)
	if user.Type == "pusher" {
		go workload.RunNewPusher(
			user.Schedule,
			user.Name,
			&c,
			user.Channel,
			config.DocSize,
			config.SendAttachment,
			config.DocSizeDistribution,
			user.SeqId,
			config.SleepTimeMs,
			wg,
			config.AddDocToTargetUser,
		)
	} else {
		go workload.RunNewPuller(
			user.Schedule,
			&c,
			user.Channel,
			user.Name,
			config.FeedType,
			wg,
		)
	}
	log.Printf("------ Done Starting new %s (%s)", user.Type, user.Name)

}

// At the end of the run, write the full list of expvars to a file
func writeExpvarsToFile() {

	// read http
	url := "http://localhost:9876/debug/vars"
	resp, err := http.Get(url)
	if err != nil {
		log.Fatalf("Error writing expvars, failed connection to: %v", url)
	}
	defer resp.Body.Close()

	// write to file
	destFileName := "gateload_expvars.json"
	destFile, err := os.Create(destFileName)
	if err != nil {
		log.Fatalf("Error opening file for writing to :%v", destFileName)
	}
	_, err = io.Copy(destFile, resp.Body)
	if err != nil {
		log.Fatalf("Error copying from %v -> %v", url, destFile)
	}

	log.Printf("Wrote results to %v", destFileName)

}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"math"
	"os"
	"os/signal"
	"strings"
	"time"

	"github.com/bcurren/go-hue"
	"github.com/bitly/go-simplejson"
	"github.com/davecgh/go-spew/spew"
	// "github.com/ninjasphere/driver-go-hue/bulbmonitor"
	"github.com/ninjasphere/go-ninja"
)

var _ = fmt.Printf

type Light struct {
	Id            string
	Name          string
	Bus           *ninja.DeviceBus
	OnOffBus      *ninja.ChannelBus
	colorBus      *ninja.ChannelBus
	brightnessBus *ninja.ChannelBus
	Bridge        *hue.Bridge
	User          *hue.User
	LightState    *hue.LightState
	Batch         bool
	batchBus      *ninja.ChannelBus
	//bulbMonitor   *bulbmonitor.BulbMonitor
}

//Returns json state as defined by Ninja light protocol
func (l Light) GetJsonLightState() *simplejson.Json {
	st := l.LightState
	js := simplejson.New()
	js.Set("on", st.On)
	js.Set("bri", st.Brightness)
	js.Set("sat", st.Saturation)
	js.Set("hue", st.Hue)
	js.Set("ct", st.ColorTemp)
	js.Set("transitionTime", st.TransitionTime)
	js.Set("alert", st.Alert)
	js.Set("xy", st.XY)
	return js
}

func getBridge() *hue.Bridge {
	nobridge := true
	var allbridges []*hue.Bridge
	for nobridge {
		allbridges, _ = hue.FindBridges()
		if len(allbridges) == 0 {
			log.Printf("Couldn't find bridge, retrying")
			time.Sleep(time.Second * 2) //this sucks
		} else {
			nobridge = false
			log.Printf("got %d bridges: %s", len(allbridges), allbridges)
		}
	}
	return allbridges[0]
}

func getUser(bridge *hue.Bridge) *hue.User {
	var user *hue.User
	var err error
	noUser := true
	retries := 0
	serial, err := ninja.GetSerial()
	if err != nil {
		log.Fatalf("Problem determining if hue user is valid: %s", err)
	}
	username := serial + serial //username must be long 10-40 characters
	isvaliduser, err := bridge.IsValidUser(username)
	if err != nil {
		log.Printf("Problem determining if hue user is valid")
	}

	if isvaliduser {
		user = hue.NewUserWithBridge(username, bridge)
	} else {
		for noUser {
			user, err = bridge.CreateUser("ninjadevice", username)
			if err != nil {
				if strings.Contains(err.Error(), "101") { // there's probably a nicer way to check this
					retries++
					log.Printf("Couldn't make user, push link button. Retry: %d", retries)
					time.Sleep(time.Second * 2) //this sucks
				} else {
					log.Fatalf("Error creating user: %s", err)
				}
			}

			if user != nil {
				noUser = false
			}
		}
	}
	return user
}

func getOnOffBus(light *Light) *ninja.ChannelBus {
	methods := []string{"turnOn", "turnOff", "set"}
	events := []string{"state"}
	onOffBus, _ := light.Bus.AnnounceChannel("on-off", "on-off", methods, events, func(method string, payload *simplejson.Json) {
		if light.Batch == true {
			return
		}
		switch method {
		case "turnOn":
			light.turnOnOff(true)
		case "turnOff":
			light.refreshLightState()
			light.turnOnOff(false)
		case "set":
			state, _ := payload.GetIndex(0).Bool()
			log.Printf("Setting to %t!", state)
			light.turnOnOff(state)
		default:
			log.Printf("On-off got an unknown method %s", method)
			return
		}
	})

	return onOffBus
}

func getBrightBus(light *Light) *ninja.ChannelBus {
	methods := []string{"set"}
	events := []string{"state"}
	brightnessBus, _ := light.Bus.AnnounceChannel("brightness", "brightness", methods, events, func(method string, payload *simplejson.Json) {
		if light.Batch == true {
			return
		}

		switch method {
		case "set":
			brightness, _ := payload.GetIndex(0).Float64()
			log.Printf("Setting brightness to %f!", brightness)
			light.setBrightness(brightness)
		default:
			log.Printf("Brightness got an unknown method %s", method)
			return
		}

	})

	return brightnessBus

}

func getColorBus(light *Light) *ninja.ChannelBus {
	methods := []string{"set"}
	events := []string{"state"}
	colorBus, _ := light.Bus.AnnounceChannel("color", "color", methods, events, func(method string, payload *simplejson.Json) {
		if light.Batch == true {
			return
		}
		switch method {
		case "set":
			log.Printf("Setting color to %s!", payload)
			mode, err := payload.Get("mode").String()
			if err != nil {
				log.Printf("No mode sent to color bus: %s", err)
				spew.Dump(payload)
			}
			light.setColor(payload, mode)
		default:
			log.Printf("Color got an unknown method %s", method)
		}
	})

	return colorBus
}

func getBatchBus(light *Light) *ninja.ChannelBus {
	methods := []string{"setBatch"}
	events := []string{"state"}
	batchBus, _ := light.Bus.AnnounceChannel("core.batching", "core.batching", methods, events, func(method string, payload *simplejson.Json) {
		switch method {
		case "setBatch":
			light.setBatchColor(payload.GetIndex(0))
		default:
			log.Printf("Color got an unknown method %s", method)
			return
		}
	})

	return batchBus
}

func NewLight(l *hue.Light, bus *ninja.DriverBus, bridge *hue.Bridge, user *hue.User) (*Light, error) { //TODO cut this down!

	lightState := createLightState()

	light := &Light{
		Id:         l.Id,
		Name:       l.Name,
		Bridge:     bridge,
		User:       user,
		LightState: lightState,
		Batch:      false,
	}

	sigs, _ := simplejson.NewJson([]byte(`{
			"ninja:manufacturer": "Phillips",
			"ninja:productName": "Hue",
			"manufacturer:productModelId": "",
			"ninja:productType": "Light",
			"ninja:thingType": "light"
	}`))

	la, _ := user.GetLightAttributes(l.Id)
	sigs.Set("manufacturer:productModelId", la.ModelId)

	deviceBus, _ := bus.AnnounceDevice(l.Id, "hue", l.Name, sigs)
	light.Bus = deviceBus
	light.OnOffBus = getOnOffBus(light)
	light.brightnessBus = getBrightBus(light)
	light.colorBus = getColorBus(light)
	light.batchBus = getBatchBus(light)

	return light, nil
}

func (l Light) StartBatch() {
	l.Batch = true
}

func (l Light) EndBatch() {
	l.Batch = false
	l.User.SetLightState(l.Id, l.LightState)
	l.OnOffBus.SendEvent("state", l.GetJsonLightState())
	spew.Dump(l.LightState)
}

func (l Light) turnOnOff(state bool) {
	if !l.Batch {
		lightState := &hue.LightState{
			On: &state,
		}
		l.User.SetLightState(l.Id, lightState)

	}
}

func (l Light) setBrightness(fbrightness float64) {
	l.refreshLightState()
	brightness := uint8(fbrightness * math.MaxUint8)
	on := bool(true)
	l.LightState.Brightness = &brightness
	l.LightState.On = &on
	if !l.Batch {
		l.User.SetLightState(l.Id, l.LightState)
		l.brightnessBus.SendEvent("state", l.GetJsonLightState())
	}
}

func (l Light) setColor(payload *simplejson.Json, mode string) {
	l.refreshLightState()
	switch mode {
	case "hue": //TODO less verbose plz
		if trans, e := payload.Get("transition").Int(); e == nil {
			l.setTransition(trans)
		}
		fhue, _ := payload.Get("hue").Float64()
		hue := uint16(fhue * math.MaxUint16)
		fsaturation, _ := payload.Get("saturation").Float64()
		saturation := uint8(fsaturation * math.MaxUint8)
		on := bool(true)
		l.LightState.Hue = &hue
		l.LightState.Saturation = &saturation
		l.LightState.On = &on
		l.LightState.XY = nil
		l.LightState.ColorTemp = nil
	case "xy":
		if trans, e := payload.Get("transition").Int(); e == nil {
			l.setTransition(trans)
		}
		x, _ := payload.Get("x").Float64()
		y, _ := payload.Get("y").Float64()
		xy := []float64{x, y}
		l.LightState.XY = xy
		l.LightState.Hue = nil
		l.LightState.Saturation = nil
		l.LightState.ColorTemp = nil
	case "temperature":
		if trans, e := payload.Get("transition").Int(); e == nil {
			l.setTransition(trans)
		}
		temp, _ := payload.Get("temperature").Float64()
		utemp := uint16(math.Floor(1000000 / temp))
		l.LightState.ColorTemp = &utemp
		l.LightState.XY = nil
		l.LightState.Hue = nil
		l.LightState.Saturation = nil
	default:
		log.Printf("Bad color mode: %s", mode)
		return
	}

	if !l.Batch {
		l.User.SetLightState(l.Id, l.LightState)
		l.colorBus.SendEvent("state", l.GetJsonLightState())
	}

}

func (l Light) setTransition(transTime int) {
	transTime = transTime / 10 //HUE API uses 1/10th of a second
	utranstime := uint16(transTime)
	l.LightState.TransitionTime = &utranstime
}

func (l Light) setBatchColor(payload *simplejson.Json) { //TODO This will set each param individually. Better to build full state then send to bulb.
	l.StartBatch()

	color := payload.Get("color")
	if color != nil {
		l.setColor(color, "hue")
		prettycolor, _ := color.EncodePretty()
		log.Printf("Got color: %s", prettycolor)
	}

	if brightness, err := payload.Get("brightness").Float64(); err == nil {
		log.Printf("Got brightness: %f", brightness)
		l.setBrightness(brightness)
	}

	if onoff, err := payload.Get("on-off").Bool(); err == nil {
		log.Printf("Got onoff: %t", onoff)
		l.turnOnOff(onoff)
	}

	if transition, err := payload.Get("transition").Int(); err == nil {
		log.Printf("Got transition: %d", transition)
		l.setTransition(transition)
	}

	l.EndBatch()
}

func createLightState() *hue.LightState {

	on := bool(false)
	brightness := uint8(0)
	saturation := uint8(0)
	hueVal := uint16(0)
	transitionTime := uint16(0)
	alert := ""
	temp := uint16(0)
	xy := []float64{0, 0}

	lightState := &hue.LightState{
		On:             &on,
		Brightness:     &brightness,
		Saturation:     &saturation,
		Hue:            &hueVal,
		ColorTemp:      &temp,
		TransitionTime: &transitionTime,
		Alert:          alert,
		XY:             xy,
	}

	return lightState
}

func getCurDir() string {
	pwd, _ := os.Getwd()
	return pwd + "/"
}

func (l Light) sendLightState() {

	l.User.SetLightState(l.Id, l.LightState)
	l.OnOffBus.SendEvent("state", l.GetJsonLightState())
}

func (l Light) refreshLightState() { //TOOD fix verboseness
	newstate, _ := l.User.GetLightAttributes(l.Id)
	bulbstate := newstate.State
	mybulbstate := l.LightState
	transtime := uint16(5) //TODO: Remove when web is sending sensible value
	// l.LightState = newstate.State //TODO why doesnt this work?

	mybulbstate.On = bulbstate.On
	mybulbstate.Brightness = bulbstate.Brightness
	mybulbstate.Hue = bulbstate.Hue
	mybulbstate.Saturation = bulbstate.Saturation
	mybulbstate.XY = bulbstate.XY
	mybulbstate.ColorTemp = bulbstate.ColorTemp
	mybulbstate.Alert = bulbstate.Alert
	mybulbstate.Effect = bulbstate.Effect
	mybulbstate.TransitionTime = &transtime

}

func printState(s *hue.LightState) {
	spew.Dump(s)
}

func main() {

	conn, err := ninja.Connect("com.ninjablocks.hue")
	if err != nil {
		log.Fatalf("Could not connect to MQTT: %s", err)
	}

	bus, err := conn.AnnounceDriver("com.ninjablocks.hue", "driver-hue", getCurDir())
	if err != nil {
		log.Fatalf("Could not get driver bus: %s", err)
	}

	bridge := getBridge()
	user := getUser(bridge)

	allLights, err := user.GetLights()
	if err != nil {
		log.Fatalf("Couldn't get lights:  %s", err)
	}

	for _, l := range allLights {
		_, err := NewLight(&l, bus, bridge, user)
		if err != nil {
			log.Fatalf("Error creating light instance:  %s", err)
		}

	}

	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, os.Kill)

	// Block until a signal is received.
	s := <-c
	fmt.Println("Got signal:", s)

}

// func verifyState (sent *simpleJson) bool { TODO
//if sent state == current state, return true
//else return false
// }
<commit_msg>Support different color modes in setBatchColor<commit_after>package main

import (
	"fmt"
	"log"
	"math"
	"os"
	"os/signal"
	"strings"
	"time"

	"github.com/bcurren/go-hue"
	"github.com/bitly/go-simplejson"
	"github.com/davecgh/go-spew/spew"
	// "github.com/ninjasphere/driver-go-hue/bulbmonitor"
	"github.com/ninjasphere/go-ninja"
)

var _ = fmt.Printf

type Light struct {
	Id            string
	Name          string
	Bus           *ninja.DeviceBus
	OnOffBus      *ninja.ChannelBus
	colorBus      *ninja.ChannelBus
	brightnessBus *ninja.ChannelBus
	Bridge        *hue.Bridge
	User          *hue.User
	LightState    *hue.LightState
	Batch         bool
	batchBus      *ninja.ChannelBus
	//bulbMonitor   *bulbmonitor.BulbMonitor
}

//Returns json state as defined by Ninja light protocol
func (l Light) GetJsonLightState() *simplejson.Json {
	st := l.LightState
	js := simplejson.New()
	js.Set("on", st.On)
	js.Set("bri", st.Brightness)
	js.Set("sat", st.Saturation)
	js.Set("hue", st.Hue)
	js.Set("ct", st.ColorTemp)
	js.Set("transitionTime", st.TransitionTime)
	js.Set("alert", st.Alert)
	js.Set("xy", st.XY)
	return js
}

func getBridge() *hue.Bridge {
	nobridge := true
	var allbridges []*hue.Bridge
	for nobridge {
		allbridges, _ = hue.FindBridges()
		if len(allbridges) == 0 {
			log.Printf("Couldn't find bridge, retrying")
			time.Sleep(time.Second * 2) //this sucks
		} else {
			nobridge = false
			log.Printf("got %d bridges: %s", len(allbridges), allbridges)
		}
	}
	return allbridges[0]
}

func getUser(bridge *hue.Bridge) *hue.User {
	var user *hue.User
	var err error
	noUser := true
	retries := 0
	serial, err := ninja.GetSerial()
	if err != nil {
		log.Fatalf("Problem determining if hue user is valid: %s", err)
	}
	username := serial + serial //username must be long 10-40 characters
	isvaliduser, err := bridge.IsValidUser(username)
	if err != nil {
		log.Printf("Problem determining if hue user is valid")
	}

	if isvaliduser {
		user = hue.NewUserWithBridge(username, bridge)
	} else {
		for noUser {
			user, err = bridge.CreateUser("ninjadevice", username)
			if err != nil {
				if strings.Contains(err.Error(), "101") { // there's probably a nicer way to check this
					retries++
					log.Printf("Couldn't make user, push link button. Retry: %d", retries)
					time.Sleep(time.Second * 2) //this sucks
				} else {
					log.Fatalf("Error creating user: %s", err)
				}
			}

			if user != nil {
				noUser = false
			}
		}
	}
	return user
}

func getOnOffBus(light *Light) *ninja.ChannelBus {
	methods := []string{"turnOn", "turnOff", "set"}
	events := []string{"state"}
	onOffBus, _ := light.Bus.AnnounceChannel("on-off", "on-off", methods, events, func(method string, payload *simplejson.Json) {
		if light.Batch == true {
			return
		}
		switch method {
		case "turnOn":
			light.turnOnOff(true)
		case "turnOff":
			light.refreshLightState()
			light.turnOnOff(false)
		case "set":
			state, _ := payload.GetIndex(0).Bool()
			log.Printf("Setting to %t!", state)
			light.turnOnOff(state)
		default:
			log.Printf("On-off got an unknown method %s", method)
			return
		}
	})

	return onOffBus
}

func getBrightBus(light *Light) *ninja.ChannelBus {
	methods := []string{"set"}
	events := []string{"state"}
	brightnessBus, _ := light.Bus.AnnounceChannel("brightness", "brightness", methods, events, func(method string, payload *simplejson.Json) {
		if light.Batch == true {
			return
		}

		switch method {
		case "set":
			brightness, _ := payload.GetIndex(0).Float64()
			log.Printf("Setting brightness to %f!", brightness)
			light.setBrightness(brightness)
		default:
			log.Printf("Brightness got an unknown method %s", method)
			return
		}

	})

	return brightnessBus

}

func getColorBus(light *Light) *ninja.ChannelBus {
	methods := []string{"set"}
	events := []string{"state"}
	colorBus, _ := light.Bus.AnnounceChannel("color", "color", methods, events, func(method string, payload *simplejson.Json) {
		if light.Batch == true {
			return
		}
		switch method {
		case "set":
			log.Printf("Setting color to %s!", payload)
			mode, err := payload.Get("mode").String()
			if err != nil {
				log.Printf("No mode sent to color bus: %s", err)
				spew.Dump(payload)
			}
			light.setColor(payload, mode)
		default:
			log.Printf("Color got an unknown method %s", method)
		}
	})

	return colorBus
}

func getBatchBus(light *Light) *ninja.ChannelBus {
	methods := []string{"setBatch"}
	events := []string{"state"}
	batchBus, _ := light.Bus.AnnounceChannel("core.batching", "core.batching", methods, events, func(method string, payload *simplejson.Json) {
		switch method {
		case "setBatch":
			light.setBatchColor(payload.GetIndex(0))
		default:
			log.Printf("Color got an unknown method %s", method)
			return
		}
	})

	return batchBus
}

func NewLight(l *hue.Light, bus *ninja.DriverBus, bridge *hue.Bridge, user *hue.User) (*Light, error) { //TODO cut this down!

	lightState := createLightState()

	light := &Light{
		Id:         l.Id,
		Name:       l.Name,
		Bridge:     bridge,
		User:       user,
		LightState: lightState,
		Batch:      false,
	}

	sigs, _ := simplejson.NewJson([]byte(`{
			"ninja:manufacturer": "Phillips",
			"ninja:productName": "Hue",
			"manufacturer:productModelId": "",
			"ninja:productType": "Light",
			"ninja:thingType": "light"
	}`))

	la, _ := user.GetLightAttributes(l.Id)
	sigs.Set("manufacturer:productModelId", la.ModelId)

	deviceBus, _ := bus.AnnounceDevice(l.Id, "hue", l.Name, sigs)
	light.Bus = deviceBus
	light.OnOffBus = getOnOffBus(light)
	light.brightnessBus = getBrightBus(light)
	light.colorBus = getColorBus(light)
	light.batchBus = getBatchBus(light)

	return light, nil
}

func (l Light) StartBatch() {
	l.Batch = true
}

func (l Light) EndBatch() {
	l.Batch = false
	l.User.SetLightState(l.Id, l.LightState)
	l.OnOffBus.SendEvent("state", l.GetJsonLightState())
	spew.Dump(l.LightState)
}

func (l Light) turnOnOff(state bool) {
	if !l.Batch {
		lightState := &hue.LightState{
			On: &state,
		}
		l.User.SetLightState(l.Id, lightState)

	}
}

func (l Light) setBrightness(fbrightness float64) {
	l.refreshLightState()
	brightness := uint8(fbrightness * math.MaxUint8)
	on := bool(true)
	l.LightState.Brightness = &brightness
	l.LightState.On = &on
	if !l.Batch {
		l.User.SetLightState(l.Id, l.LightState)
		l.brightnessBus.SendEvent("state", l.GetJsonLightState())
	}
}

func (l Light) setColor(payload *simplejson.Json, mode string) {
	l.refreshLightState()
	switch mode {
	case "hue": //TODO less verbose plz
		if trans, e := payload.Get("transition").Int(); e == nil {
			l.setTransition(trans)
		}
		fhue, _ := payload.Get("hue").Float64()
		hue := uint16(fhue * math.MaxUint16)
		fsaturation, _ := payload.Get("saturation").Float64()
		saturation := uint8(fsaturation * math.MaxUint8)
		on := bool(true)
		l.LightState.Hue = &hue
		l.LightState.Saturation = &saturation
		l.LightState.On = &on
		l.LightState.XY = nil
		l.LightState.ColorTemp = nil
	case "xy":
		if trans, e := payload.Get("transition").Int(); e == nil {
			l.setTransition(trans)
		}
		x, _ := payload.Get("x").Float64()
		y, _ := payload.Get("y").Float64()
		xy := []float64{x, y}
		l.LightState.XY = xy
		l.LightState.Hue = nil
		l.LightState.Saturation = nil
		l.LightState.ColorTemp = nil
	case "temperature":
		if trans, e := payload.Get("transition").Int(); e == nil {
			l.setTransition(trans)
		}
		temp, _ := payload.Get("temperature").Float64()
		utemp := uint16(math.Floor(1000000 / temp))
		l.LightState.ColorTemp = &utemp
		l.LightState.XY = nil
		l.LightState.Hue = nil
		l.LightState.Saturation = nil
	default:
		log.Printf("Bad color mode: %s", mode)
		return
	}

	if !l.Batch {
		l.User.SetLightState(l.Id, l.LightState)
		l.colorBus.SendEvent("state", l.GetJsonLightState())
	}

}

func (l Light) setTransition(transTime int) {
	transTime = transTime / 10 //HUE API uses 1/10th of a second
	utranstime := uint16(transTime)
	l.LightState.TransitionTime = &utranstime
}

func (l Light) setBatchColor(payload *simplejson.Json) { //TODO This will set each param individually. Better to build full state then send to bulb.
	l.StartBatch()

	color := payload.Get("color")

	if mode, err := payload.Get("mode").String(); err == nil {
		if color != nil {
			log.Printf("Got color mode: %s", mode)
			log.Printf("Got color: %s", color)
			l.setColor(color, mode)
		}
	}

	if brightness, err := payload.Get("brightness").Float64(); err == nil {
		log.Printf("Got brightness: %f", brightness)
		l.setBrightness(brightness)
	}

	if onoff, err := payload.Get("on-off").Bool(); err == nil {
		log.Printf("Got onoff: %t", onoff)
		l.turnOnOff(onoff)
	}

	if transition, err := payload.Get("transition").Int(); err == nil {
		log.Printf("Got transition: %d", transition)
		l.setTransition(transition)
	}

	l.EndBatch()
}

func createLightState() *hue.LightState {

	on := bool(false)
	brightness := uint8(0)
	saturation := uint8(0)
	hueVal := uint16(0)
	transitionTime := uint16(0)
	alert := ""
	temp := uint16(0)
	xy := []float64{0, 0}

	lightState := &hue.LightState{
		On:             &on,
		Brightness:     &brightness,
		Saturation:     &saturation,
		Hue:            &hueVal,
		ColorTemp:      &temp,
		TransitionTime: &transitionTime,
		Alert:          alert,
		XY:             xy,
	}

	return lightState
}

func getCurDir() string {
	pwd, _ := os.Getwd()
	return pwd + "/"
}

func (l Light) sendLightState() {

	l.User.SetLightState(l.Id, l.LightState)
	l.OnOffBus.SendEvent("state", l.GetJsonLightState())
}

func (l Light) refreshLightState() { //TOOD fix verboseness
	newstate, _ := l.User.GetLightAttributes(l.Id)
	bulbstate := newstate.State
	mybulbstate := l.LightState
	transtime := uint16(5) //TODO: Remove when web is sending sensible value
	// l.LightState = newstate.State //TODO why doesnt this work?

	mybulbstate.On = bulbstate.On
	mybulbstate.Brightness = bulbstate.Brightness
	mybulbstate.Hue = bulbstate.Hue
	mybulbstate.Saturation = bulbstate.Saturation
	mybulbstate.XY = bulbstate.XY
	mybulbstate.ColorTemp = bulbstate.ColorTemp
	mybulbstate.Alert = bulbstate.Alert
	mybulbstate.Effect = bulbstate.Effect
	mybulbstate.TransitionTime = &transtime

}

func printState(s *hue.LightState) {
	spew.Dump(s)
}

func main() {

	conn, err := ninja.Connect("com.ninjablocks.hue")
	if err != nil {
		log.Fatalf("Could not connect to MQTT: %s", err)
	}

	bus, err := conn.AnnounceDriver("com.ninjablocks.hue", "driver-hue", getCurDir())
	if err != nil {
		log.Fatalf("Could not get driver bus: %s", err)
	}

	bridge := getBridge()
	user := getUser(bridge)

	allLights, err := user.GetLights()
	if err != nil {
		log.Fatalf("Couldn't get lights:  %s", err)
	}

	for _, l := range allLights {
		_, err := NewLight(&l, bus, bridge, user)
		if err != nil {
			log.Fatalf("Error creating light instance:  %s", err)
		}

	}

	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, os.Kill)

	// Block until a signal is received.
	s := <-c
	fmt.Println("Got signal:", s)

}

// func verifyState (sent *simpleJson) bool { TODO
//if sent state == current state, return true
//else return false
// }
<|endoftext|>


<commit_before>package main

import (
	"github.com/solidfire/solidfire-docker-driver/sfapi"
	"github.com/solidfire/solidfire-docker-driver/sfcli"
	"os"
)

const (
	VERSION = "1.3.0"
)

var (
	client *sfapi.Client
)

func main() {
	cli := sfcli.NewCli(VERSION)
	cli.Run(os.Args)

}
<commit_msg>Version bump 1.3.0=>1.3.1<commit_after>package main

import (
	"github.com/solidfire/solidfire-docker-driver/sfapi"
	"github.com/solidfire/solidfire-docker-driver/sfcli"
	"os"
)

const (
	VERSION = "1.3.1"
)

var (
	client *sfapi.Client
)

func main() {
	cli := sfcli.NewCli(VERSION)
	cli.Run(os.Args)

}
<|endoftext|>


<commit_before>package main

import (
	"github.com/mmstick/i3gostatusbar/battery"
	"github.com/mmstick/i3gostatusbar/cpu"
	"github.com/mmstick/i3gostatusbar/memory"
	"github.com/mmstick/i3gostatusbar/network"
	"github.com/mmstick/i3gostatusbar/system"
	"github.com/mmstick/i3gostatusbar/uptime"
	"fmt"
	"runtime"
	"time"
)

var refreshRate = 1 * time.Second

// Returns the printf format for formatting the status bar. If a battery exists,
// this will return an additional string element.
func statusBarFormat(batteryExists bool) string {
	if batteryExists {
		return "%s@%s | %s | %s | %s %s | %s | %s | %s %s %s | %s\n"
	} else {
		return "%s@%s | %s | %s | %s %s | %s | %s %s %s | %s\n"
	}
}

// Returns system information that does not need to be dynamically updated.
func getStaticSystemInformation() *system.Info {
	info := system.Info{
		Kernel:   system.KernelVersion(),
		Model:    cpu.Model(),
		MemTotal: memory.Installed(),
		Host:     system.Host(),
		User:     system.Username(),
		NetName:  network.Name(),
		NetSpeed: network.Speed(),
	}
	return &info
}

// Adds dynamic system information to the systemInfo struct and checks for
// the existence of a battery.
func getDynamicSystemInformation(info system.Info) (*system.Info, bool) {
	batteryExists, jobs := battery.Exists()
	synchronize := make(chan bool, jobs)
	if batteryExists {
		go battery.Information(&info.BatteryInfo, synchronize)
	}
	go uptime.Get(&info.Uptime, synchronize)
	go cpu.Frequencies(&info.Cpufreqs, synchronize)
	go memory.Statistics(&info.MemTotal, &info.MemStat, synchronize)
	go network.Statistics(&info.NetStat, synchronize)
	go system.CurrentTime(&info.Date, synchronize)
	for jobCount := 0; jobCount < jobs; jobCount++ {
		<-synchronize
	}
	return &info, batteryExists
}

// Refreshes the status bar
func refreshBar(info *system.Info, batteryExists bool) {
	if batteryExists {
		fmt.Printf(statusBarFormat(true), info.User, info.Host,
			info.Kernel, info.Uptime, info.Model, info.Cpufreqs,
			info.MemStat, info.NetName, info.NetSpeed, info.NetStat,
			info.BatteryInfo, info.Date)
	} else {
		fmt.Printf(statusBarFormat(false), info.User, info.Host,
			info.Kernel, info.Uptime, info.Model, info.Cpufreqs,
			info.MemStat, info.NetName, info.NetSpeed, info.NetStat,
			info.Date)
	}
}

func main() {
	runtime.GOMAXPROCS(6)
	system := getStaticSystemInformation()
	for {
		go refreshBar(getDynamicSystemInformation(*system))
		time.Sleep(refreshRate)
	}
}
<commit_msg>Fix Status Bar Format<commit_after>package main

import (
	"github.com/mmstick/i3gostatusbar/battery"
	"github.com/mmstick/i3gostatusbar/cpu"
	"github.com/mmstick/i3gostatusbar/memory"
	"github.com/mmstick/i3gostatusbar/network"
	"github.com/mmstick/i3gostatusbar/system"
	"github.com/mmstick/i3gostatusbar/uptime"
	"fmt"
	"runtime"
	"time"
)

var refreshRate = 1 * time.Second

// Returns the printf format for formatting the status bar. If a battery exists,
// this will return an additional string element.
func statusBarFormat(batteryExists bool) string {
	if batteryExists {
		return "%s@%s | %s | %s | %s %s | %s | %s %s %s | %s | %s\n"
	} else {
		return "%s@%s | %s | %s | %s %s | %s | %s %s %s | %s\n"
	}
}

// Returns system information that does not need to be dynamically updated.
func getStaticSystemInformation() *system.Info {
	info := system.Info{
		Kernel:   system.KernelVersion(),
		Model:    cpu.Model(),
		MemTotal: memory.Installed(),
		Host:     system.Host(),
		User:     system.Username(),
		NetName:  network.Name(),
		NetSpeed: network.Speed(),
	}
	return &info
}

// Adds dynamic system information to the systemInfo struct and checks for
// the existence of a battery.
func getDynamicSystemInformation(info system.Info) (*system.Info, bool) {
	batteryExists, jobs := battery.Exists()
	synchronize := make(chan bool, jobs)
	if batteryExists {
		go battery.Information(&info.BatteryInfo, synchronize)
	}
	go uptime.Get(&info.Uptime, synchronize)
	go cpu.Frequencies(&info.Cpufreqs, synchronize)
	go memory.Statistics(&info.MemTotal, &info.MemStat, synchronize)
	go network.Statistics(&info.NetStat, synchronize)
	go system.CurrentTime(&info.Date, synchronize)
	for jobCount := 0; jobCount < jobs; jobCount++ {
		<-synchronize
	}
	return &info, batteryExists
}

// Refreshes the status bar
func refreshBar(info *system.Info, batteryExists bool) {
	if batteryExists {
		fmt.Printf(statusBarFormat(true), info.User, info.Host,
			info.Kernel, info.Uptime, info.Model, info.Cpufreqs,
			info.MemStat, info.NetName, info.NetSpeed, info.NetStat,
			info.BatteryInfo, info.Date)
	} else {
		fmt.Printf(statusBarFormat(false), info.User, info.Host,
			info.Kernel, info.Uptime, info.Model, info.Cpufreqs,
			info.MemStat, info.NetName, info.NetSpeed, info.NetStat,
			info.Date)
	}
}

func main() {
	runtime.GOMAXPROCS(6)
	system := getStaticSystemInformation()
	for {
		go refreshBar(getDynamicSystemInformation(*system))
		time.Sleep(refreshRate)
	}
}
<|endoftext|>


<commit_before>package main

import (
	r "github.com/scascketta/capmetro-log/Godeps/_workspace/src/github.com/dancannon/gorethink"
	"log"
	"os"
	"sync"
	"time"
)

var (
	errlogger *log.Logger = log.New(os.Stderr, "[ERR] ", log.LstdFlags|log.Lshortfile)
	session   *r.Session
	DB_NAME   string        = os.Getenv("DB_NAME")
	connOpts  r.ConnectOpts = r.ConnectOpts{Address: "localhost:28015", Database: DB_NAME}
	routes    []string      = []string{"803", "801", "550"}

	normalDuration   time.Duration        = 30 * (1000 * time.Millisecond)
	extendedDuration time.Duration        = (10 * 60) * (1000 * time.Millisecond)
	lastUpdated      map[string]time.Time = map[string]time.Time{}
	sleepHistory     map[string][]bool    = map[string][]bool{}
)

func init() {
	if len(os.Getenv("DB_NAME")) == 0 {
		errlogger.Fatal("Missing envvar DB_NAME")
	}
}

func FilterUpdatedVehicles(vehicles []VehiclePosition) []VehiclePosition {
	updated := []VehiclePosition{}
	for _, v := range vehicles {
		updateTime, _ := lastUpdated[v.VehicleID]
		lastUpdated[v.VehicleID] = v.Time
		if !updateTime.Equal(v.Time) {
			updated = append(updated, v)
		}
	}
	return updated
}

func LogVehiclePositions(session *r.Session, route string) {
	b, err := FetchVehicles(route)
	if err != nil {
		errlogger.Println(err)
		return
	}

	vehicles, err := ParseVehiclesResponse(b)
	if err != nil {
		errlogger.Println(err)
		return
	}
	if vehicles == nil {
		sleepHistory[route] = append(sleepHistory[route], true)
		return
	}

	updated := FilterUpdatedVehicles(vehicles)

	if len(updated) > 0 {
		_, err = r.Table("vehicle_position").Insert(r.Expr(updated)).Run(session)
		if err != nil {
			errlogger.Println(err)
			return
		}
		log.Printf("Log %d vehicles, route %s.\n", len(updated), route)
	} else {
		log.Printf("No new vehicle positions to record for route %s.\n", route)
	}
}

// Check if the the routes are inactive
// There must have been three previous attempts to fetch data,
// and all attempts must have failed
func routesAreSleeping() bool {
	for _, b := range sleepHistory {
		if len(b) < 3 {
			return false
		}
		for _, v := range b {
			if v == false {
				return false
			}
		}
	}
	return true
}

func main() {
	for _, route := range routes {
		sleepHistory[route] = []bool{}
	}

	session, err := r.Connect(connOpts)
	if err != nil {
		errlogger.Fatal(err)
	}
	log.Printf("Established connection to RethinkDB server at %s.\n", connOpts.Address)

	var wg sync.WaitGroup

	for {
		for _, route := range routes {
			wg.Add(1)
			go func(session *r.Session, route string) {
				LogVehiclePositions(session, route)
				wg.Done()
			}(session, route)
		}
		wg.Wait()

		var duration time.Duration
		if routesAreSleeping() {
			for k, _ := range sleepHistory {
				sleepHistory[k] = []bool{}
			}
			log.Println("Sleeping for extended duration!")
			duration = extendedDuration
		} else {
			log.Println("Sleeping for normal duration!")
			duration = normalDuration
		}

		time.Sleep(duration)
		log.Println("Wake up!")
	}
}
<commit_msg>Simplify fetch retries<commit_after>package main

import (
	r "github.com/scascketta/capmetro-log/Godeps/_workspace/src/github.com/dancannon/gorethink"
	"log"
	"os"
	"sync"
	"time"
)

const MAX_RETRIES int = 5

var (
	errlogger *log.Logger = log.New(os.Stderr, "[ERR] ", log.LstdFlags|log.Lshortfile)
	session   *r.Session
	DB_NAME   string        = os.Getenv("DB_NAME")
	connOpts  r.ConnectOpts = r.ConnectOpts{Address: "localhost:28015", Database: DB_NAME}
	routes    []string      = []string{"803", "801", "550"}

	lastUpdated      map[string]time.Time = map[string]time.Time{}
	normalDuration   time.Duration        = 30 * (1000 * time.Millisecond)
	extendedDuration time.Duration        = (10 * 60) * (1000 * time.Millisecond)
	sleepHistory     map[string]int       = map[string]int{}
)

func init() {
	if len(os.Getenv("DB_NAME")) == 0 {
		errlogger.Fatal("Missing envvar DB_NAME")
	}
}

func FilterUpdatedVehicles(vehicles []VehiclePosition) []VehiclePosition {
	updated := []VehiclePosition{}
	for _, v := range vehicles {
		updateTime, _ := lastUpdated[v.VehicleID]
		lastUpdated[v.VehicleID] = v.Time
		if !updateTime.Equal(v.Time) {
			updated = append(updated, v)
		}
	}
	return updated
}

func LogVehiclePositions(session *r.Session, route string) {
	b, err := FetchVehicles(route)
	if err != nil {
		errlogger.Println(err)
		return
	}

	vehicles, err := ParseVehiclesResponse(b)
	if err != nil {
		errlogger.Println(err)
		return
	}
	if vehicles == nil {
		sleepHistory[route] += 1
		log.Println("No vehicles in response")
		return
	}

	updated := FilterUpdatedVehicles(vehicles)

	if len(updated) > 0 {
		_, err = r.Table("vehicle_position").Insert(r.Expr(updated)).Run(session)
		if err != nil {
			errlogger.Println(err)
			return
		}
		log.Printf("Log %d vehicles, route %s.\n", len(updated), route)
	} else {
		log.Printf("No new vehicle positions to record for route %s.\n", route)
	}
}

// Check if the the routes are inactive
// There must have been MAX_RETRIES previous attempts to fetch data,
// and all attempts must have failed
func routesAreSleeping() bool {
	for _, retries := range sleepHistory {
		if retries < MAX_RETRIES {
			return false
		}
	}
	return true
}

func main() {
	for _, route := range routes {
		sleepHistory[route] = 0
	}

	session, err := r.Connect(connOpts)
	if err != nil {
		errlogger.Fatal(err)
	}
	log.Printf("Established connection to RethinkDB server at %s.\n", connOpts.Address)

	var wg sync.WaitGroup

	for {

		for _, route := range routes {
			wg.Add(1)
			go func(session *r.Session, route string) {
				LogVehiclePositions(session, route)
				wg.Done()
			}(session, route)
		}
		wg.Wait()

		var duration time.Duration
		if routesAreSleeping() {
			for k, _ := range sleepHistory {
				sleepHistory[k] = 0
			}
			log.Println("Sleeping for extended duration!")
			duration = extendedDuration
		} else {
			log.Println("Sleeping for normal duration!")
			duration = normalDuration
		}

		time.Sleep(duration)
		log.Println("Wake up!")
	}
}
<|endoftext|>


<commit_before>package qtypes

import (
	"github.com/qnib/qframe-utils"
	"time"
)

type QMsg struct {
	QmsgVersion string            `json:qmsg_version`
	Type        string            `json:"type"`
	Source      string            `json:"source"`
	SourceID    uint64            `json:"source_id"`
	Host        string            `json:"host"`
	Msg         string            `json:"short_message"`
	Time        time.Time         `json:"time"`
	TimeNano    int64             `json:"time_nano"`
	Level       int               `json:"level"` //https://en.wikipedia.org/wiki/Syslog#Severity_level
	KV          map[string]string `json:"kv"`
	Data        interface{}       `json:"data"`
}

func NewQMsg(typ, source string) QMsg {
	now := time.Now()
	return QMsg{
		QmsgVersion: "0.1.0",
		Type:        typ,
		Level:       6,
		Source:      source,
		SourceID:    qutils.GetGID(),
		Time:        now,
		TimeNano:    now.UnixNano(),
	}
}

func (qm *QMsg) TimeString() (lout string) {
	return qm.Time.Format("2006-01-02T15:04:05.999999")

}

func (qm *QMsg) LogString() (lout string) {
	switch qm.Level {
	case 0:
		lout = "EMERG"
	case 1:
		lout = "ALERT"
	case 2:
		lout = "CRIT"
	case 3:
		lout = "ERROR"
	case 4:
		lout = "WARN"
	case 5:
		lout = "NOTICE"
	case 6:
		lout = "INFO"
	case 7:
		lout = "DEBUG"
	}
	return
}
<commit_msg>add SourcePath<commit_after>package qtypes

import (
	"github.com/qnib/qframe-utils"
	"time"
)

type QMsg struct {
	QmsgVersion string            `json:qmsg_version`
	Type        string            `json:"type"`
	Source      string            `json:"source"`
	SourcePath  []string          `json:"source_path"`
	SourceID    uint64            `json:"source_id"`
	Host        string            `json:"host"`
	Msg         string            `json:"short_message"`
	Time        time.Time         `json:"time"`
	TimeNano    int64             `json:"time_nano"`
	Level       int               `json:"level"` //https://en.wikipedia.org/wiki/Syslog#Severity_level
	KV          map[string]string `json:"kv"`
	Data        interface{}       `json:"data"`
}

func NewQMsg(typ, source string) QMsg {
	now := time.Now()
	return QMsg{
		QmsgVersion: "0.1.0",
		Type:        typ,
		Level:       6,
		Source:      source,
		SourceID:    qutils.GetGID(),
		SourcePath:  []string{source},
		Time:        now,
		TimeNano:    now.UnixNano(),
	}
}

func (qm *QMsg) TimeString() (lout string) {
	return qm.Time.Format("2006-01-02T15:04:05.999999")

}

func (qm *QMsg) LogString() (lout string) {
	switch qm.Level {
	case 0:
		lout = "EMERG"
	case 1:
		lout = "ALERT"
	case 2:
		lout = "CRIT"
	case 3:
		lout = "ERROR"
	case 4:
		lout = "WARN"
	case 5:
		lout = "NOTICE"
	case 6:
		lout = "INFO"
	case 7:
		lout = "DEBUG"
	}
	return
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"log"
	"net"
	"time"

	"github.com/dasfoo/i2c"
	"github.com/dasfoo/rover/bb"
	"github.com/dasfoo/rover/mc"
	"golang.org/x/net/context"

	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/credentials"

	pb "github.com/dasfoo/rover/proto"
)

// server is used to implement roverserver.RoverServiceServer.
type server struct{}

var (
	board  *bb.BB
	motors *mc.MC

	tls      = flag.Bool("tls", false, "Connection uses TLS if true, else plain TCP")
	laddr    = flag.String("laddr", "", "laddr")
	test     = flag.Bool("test", false, "Flag for startup script")
	certFile = flag.String("cert_file", "", "The TLS cert file")
	keyFile  = flag.String("key_file", "", "The TLS key file")
)

func getError(e error) error {
	errf := grpc.Errorf // Confuse `go vet' to not check this `Errorf' call. :(
	// See https://github.com/grpc/grpc-go/issues/90
	return errf(codes.Unavailable, "%s", e.Error())
}

// MoveRover implements
func (s *server) MoveRover(ctx context.Context,
	in *pb.RoverWheelRequest) (*pb.RoverWheelResponse, error) {
	_ = motors.Left(int8(in.Left)) //TODO error check
	_ = motors.Right(int8(in.Right))
	time.Sleep(1 * time.Second)

	_ = motors.Left(0)
	_ = motors.Right(0)
	return &pb.RoverWheelResponse{}, nil
}

func (s *server) GetBatteryPercentage(ctx context.Context,
	in *pb.BatteryPercentageRequest) (*pb.BatteryPercentageResponse, error) {
	var batteryPercentage byte
	var e error
	if batteryPercentage, e = board.GetBatteryPercentage(); e != nil {
		return nil, getError(e)
	}
	return &pb.BatteryPercentageResponse{
		Battery: int32(batteryPercentage),
	}, nil
}

func (s *server) GetAmbientLight(ctx context.Context,
	in *pb.AmbientLightRequest) (*pb.AmbientLightResponse, error) {
	var light uint16
	var e error
	if light, e = board.GetAmbientLight(); e != nil {
		return nil, getError(e)
	}
	return &pb.AmbientLightResponse{
		Light: int32(light),
	}, nil
}

func (s *server) GetTemperatureAndHumidity(ctx context.Context,
	in *pb.TemperatureAndHumidityRequest) (*pb.TemperatureAndHumidityResponse, error) {
	var t, h byte
	var e error
	if t, h, e = board.GetTemperatureAndHumidity(); e != nil {
		return nil, getError(e)
	}
	return &pb.TemperatureAndHumidityResponse{
		Temperature: int32(t),
		Humidity:    int32(h),
	}, nil
}

func (s *server) ReadEncoders(ctx context.Context,
	in *pb.ReadEncodersRequest) (*pb.ReadEncodersResponse, error) {
	var leftFront, leftBack, rightFront, rightBack int32
	var e error
	if leftFront, e = motors.ReadEncoder(mc.EncoderLeftFront); e != nil {
		return nil, getError(e)
	}
	if leftBack, e = motors.ReadEncoder(mc.EncoderLeftBack); e != nil {
		return nil, getError(e)
	}
	if rightFront, e = motors.ReadEncoder(mc.EncoderRightFront); e != nil {
		return nil, getError(e)
	}
	if rightBack, e = motors.ReadEncoder(mc.EncoderRightBack); e != nil {
		return nil, getError(e)
	}
	return &pb.ReadEncodersResponse{
		LeftFront:  leftFront,
		LeftBack:   leftBack,
		RightFront: rightFront,
		RightBack:  rightBack,
	}, nil
}

func setServerOptions() ([]grpc.ServerOption, error) {
	var opts []grpc.ServerOption
	if *tls {
		creds, err := credentials.NewServerTLSFromFile(*certFile, *keyFile)
		if err != nil {
			return opts, err
		}
		return []grpc.ServerOption{grpc.Creds(creds)}, nil
	}
	return opts, nil
}

func startServer() error {
	lis, err := net.Listen("tcp", *laddr)
	if err != nil {
		log.Println("Failed to listen:", err)
		return err
	}
	opts, err := setServerOptions()
	if err != nil {
		log.Println("Failed to setup Server Options:", err)
		return err
	}
	s := grpc.NewServer(opts...)
	pb.RegisterRoverServiceServer(s, &server{})
	return s.Serve(lis)
}

func main() {
	log.SetFlags(log.LstdFlags | log.Lshortfile | log.Lmicroseconds)
	flag.Parse()
	log.Println("Properties from command line:", *laddr)
	log.Println("Flag for startup script", *test)
	if bus, err := i2c.NewBus(1); err != nil {
		log.Fatal(err)
	} else {
		// Silence i2c bus log
		//bus.SetLogger(func(string, ...interface{}) {})

		board = bb.NewBB(bus, bb.Address)
		motors = mc.NewMC(bus, mc.Address)
	}
	if err := startServer(); err != nil {
		log.Println("Failed to start server :", err)
	}
}
<commit_msg>Validate user using password<commit_after>package main

import (
	"bufio"
	"errors"
	"flag"
	"log"
	"net"
	"os"
	"strings"
	"time"

	"github.com/dasfoo/i2c"
	"github.com/dasfoo/rover/bb"
	"github.com/dasfoo/rover/mc"
	"golang.org/x/net/context"

	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/credentials"
	"google.golang.org/grpc/metadata"

	pb "github.com/dasfoo/rover/proto"
)

// server is used to implement roverserver.RoverServiceServer.
type server struct{}

var (
	board  *bb.BB
	motors *mc.MC

	tls        = flag.Bool("tls", false, "Connection uses TLS if true, else plain TCP")
	laddr      = flag.String("laddr", "", "laddr")
	test       = flag.Bool("test", false, "Flag for startup script")
	certFile   = flag.String("cert_file", "", "The TLS cert file")
	keyFile    = flag.String("key_file", "", "The TLS key file")
	configFile = flag.String("config_file", "", "The file with password for validation user")
)

func getError(e error) error {
	errf := grpc.Errorf // Confuse `go vet' to not check this `Errorf' call. :(
	// See https://github.com/grpc/grpc-go/issues/90
	return errf(codes.Unavailable, "%s", e.Error())
}

// MoveRover implements
func (s *server) MoveRover(ctx context.Context,
	in *pb.RoverWheelRequest) (*pb.RoverWheelResponse, error) {
	if err := validateUser(ctx); err != nil {
		log.Printf("UserValid: %s", err)
		return nil, err
	}
	_ = motors.Left(int8(in.Left)) //TODO error check
	_ = motors.Right(int8(in.Right))
	time.Sleep(1 * time.Second)

	_ = motors.Left(0)
	_ = motors.Right(0)
	return &pb.RoverWheelResponse{}, nil
}

func (s *server) GetBatteryPercentage(ctx context.Context,
	in *pb.BatteryPercentageRequest) (*pb.BatteryPercentageResponse, error) {
	if err := validateUser(ctx); err != nil {
		log.Printf("UserValid: %s", err)
		return nil, err
	}
	var batteryPercentage byte
	var e error
	if batteryPercentage, e = board.GetBatteryPercentage(); e != nil {
		return nil, getError(e)
	}
	return &pb.BatteryPercentageResponse{
		Battery: int32(batteryPercentage),
	}, nil
}

func (s *server) GetAmbientLight(ctx context.Context,
	in *pb.AmbientLightRequest) (*pb.AmbientLightResponse, error) {
	if err := validateUser(ctx); err != nil {
		log.Printf("UserValid: %s", err)
		return nil, err
	}
	var light uint16
	var e error
	if light, e = board.GetAmbientLight(); e != nil {
		return nil, getError(e)
	}
	return &pb.AmbientLightResponse{
		Light: int32(light),
	}, nil
}

func (s *server) GetTemperatureAndHumidity(ctx context.Context,
	in *pb.TemperatureAndHumidityRequest) (*pb.TemperatureAndHumidityResponse, error) {
	if err := validateUser(ctx); err != nil {
		log.Printf("UserValid: %s", err)
		return nil, err
	}
	var t, h byte
	var e error
	if t, h, e = board.GetTemperatureAndHumidity(); e != nil {
		return nil, getError(e)
	}
	return &pb.TemperatureAndHumidityResponse{
		Temperature: int32(t),
		Humidity:    int32(h),
	}, nil
}

func readPasswordFromFile(filePath string) (string, error) {
	f, err := os.Open(filePath)
	if err != nil {
		return "", err
	}
	defer func() {
		if err := f.Close(); err != nil {
			log.Println(err)
		}
	}()
	sc := bufio.NewScanner(f)
	for sc.Scan() {
		nameAndValue := strings.Split(sc.Text(), "=")
		if nameAndValue[0] == "CAPTURE_PASSWORD" {
			return nameAndValue[1], nil
		}
	}
	return "", errors.New("Empty file")
}

func validatePassword(password string) error {
	pwd, err := readPasswordFromFile(*configFile)
	if err != nil {
		return err
	}
	if password != pwd {
		return errors.New("Wrong password for getting data")
	}
	return nil
}

func readAuthFromMetadata(ctx context.Context) (string, error) {
	const key = "authentication"
	// FromContext returns error as a bool
	val, err := metadata.FromContext(ctx)
	if !err {
		return "", errors.New("Error appears getting metadata")
	}
	return val[key][0], nil
}

func validateUser(ctx context.Context) error {
	pwd, err := readAuthFromMetadata(ctx)
	if err != nil {
		return err
	}
	if err := validatePassword(pwd); err != nil {
		return err
	}
	return nil
}

func (s *server) ReadEncoders(ctx context.Context,
	in *pb.ReadEncodersRequest) (*pb.ReadEncodersResponse, error) {

	if err := validateUser(ctx); err != nil {
		log.Printf("UserValid: %s", err)
		return nil, err
	}

	var leftFront, leftBack, rightFront, rightBack int32
	var e error
	if leftFront, e = motors.ReadEncoder(mc.EncoderLeftFront); e != nil {
		return nil, getError(e)
	}
	if leftBack, e = motors.ReadEncoder(mc.EncoderLeftBack); e != nil {
		return nil, getError(e)
	}
	if rightFront, e = motors.ReadEncoder(mc.EncoderRightFront); e != nil {
		return nil, getError(e)
	}
	if rightBack, e = motors.ReadEncoder(mc.EncoderRightBack); e != nil {
		return nil, getError(e)
	}
	return &pb.ReadEncodersResponse{
		LeftFront:  leftFront,
		LeftBack:   leftBack,
		RightFront: rightFront,
		RightBack:  rightBack,
	}, nil
}

func setServerOptions() ([]grpc.ServerOption, error) {
	var opts []grpc.ServerOption
	if *tls {
		creds, err := credentials.NewServerTLSFromFile(*certFile, *keyFile)
		if err != nil {
			return opts, err
		}
		return []grpc.ServerOption{grpc.Creds(creds)}, nil
	}
	return opts, nil
}

func startServer() error {
	lis, err := net.Listen("tcp", *laddr)
	if err != nil {
		log.Println("Failed to listen:", err)
		return err
	}
	opts, err := setServerOptions()
	if err != nil {
		log.Println("Failed to setup Server Options:", err)
		return err
	}
	s := grpc.NewServer(opts...)
	pb.RegisterRoverServiceServer(s, &server{})
	return s.Serve(lis)
}

func main() {
	log.SetFlags(log.LstdFlags | log.Lshortfile | log.Lmicroseconds)
	flag.Parse()
	log.Println("Properties from command line:", *laddr)
	log.Println("Flag for startup script", *test)
	if bus, err := i2c.NewBus(1); err != nil {
		log.Fatal(err)
	} else {
		// Silence i2c bus log
		//bus.SetLogger(func(string, ...interface{}) {})

		board = bb.NewBB(bus, bb.Address)
		motors = mc.NewMC(bus, mc.Address)
	}
	if err := startServer(); err != nil {
		log.Println("Failed to start server :", err)
	}
}
<|endoftext|>