<commit_before>package scheduler

import (
	"errors"
	"fmt"
	"testing"
	"time"

	log "github.com/Sirupsen/logrus"
	. "github.com/smartystreets/goconvey/convey"

	"github.com/intelsdi-x/pulse/core"
	"github.com/intelsdi-x/pulse/core/cdata"
	"github.com/intelsdi-x/pulse/core/ctypes"
	"github.com/intelsdi-x/pulse/core/perror"
	"github.com/intelsdi-x/pulse/pkg/schedule"
	"github.com/intelsdi-x/pulse/scheduler/wmap"
)

type mockMetricManager struct {
	failValidatingMetrics      bool
	failValidatingMetricsAfter int
	failuredSoFar              int
	acceptedContentTypes       map[string][]string
	returnedContentTypes       map[string][]string
}

func (m *mockMetricManager) SubscribeMetricType(mt core.RequestedMetric, cd *cdata.ConfigDataNode) (core.Metric, []perror.PulseError) {
	if m.failValidatingMetrics {
		if m.failValidatingMetricsAfter > m.failuredSoFar {
			m.failuredSoFar++
			return nil, nil
		}
		return nil, []perror.PulseError{
			perror.New(errors.New("metric validation error")),
		}
	}
	return nil, nil
}

func (m *mockMetricManager) lazyContentType(key string) {
	if m.acceptedContentTypes == nil {
		m.acceptedContentTypes = make(map[string][]string)
	}
	if m.returnedContentTypes == nil {
		m.returnedContentTypes = make(map[string][]string)
	}
	if m.acceptedContentTypes[key] == nil {
		m.acceptedContentTypes[key] = []string{}
	}
	if m.returnedContentTypes[key] == nil {
		m.returnedContentTypes[key] = []string{}
	}
}

// Used to mock type from plugin
func (m *mockMetricManager) setAcceptedContentType(n string, t core.PluginType, v int, s []string) {
	key := fmt.Sprintf("%s:%d:%d", n, t, v)
	m.lazyContentType(key)
	m.acceptedContentTypes[key] = s
}

func (m *mockMetricManager) setReturnedContentType(n string, t core.PluginType, v int, s []string) {
	key := fmt.Sprintf("%s:%d:%d", n, t, v)
	m.lazyContentType(key)
	m.returnedContentTypes[key] = s
}

func (m *mockMetricManager) GetPluginContentTypes(n string, t core.PluginType, v int) ([]string, []string, error) {
	key := fmt.Sprintf("%s:%d:%d", n, t, v)
	m.lazyContentType(key)

	return m.acceptedContentTypes[key], m.returnedContentTypes[key], nil
}

func (m *mockMetricManager) UnsubscribeMetricType(mt core.Metric) {

}

func (m *mockMetricManager) CollectMetrics([]core.Metric, time.Time) ([]core.Metric, []error) {
	return nil, nil
}

func (m *mockMetricManager) PublishMetrics(contentType string, content []byte, pluginName string, pluginVersion int, config map[string]ctypes.ConfigValue) []error {
	return nil
}

func (m *mockMetricManager) ProcessMetrics(contentType string, content []byte, pluginName string, pluginVersion int, config map[string]ctypes.ConfigValue) (string, []byte, []error) {
	return "", nil, nil
}

func (m *mockMetricManager) SubscribeProcessor(name string, ver int, config map[string]ctypes.ConfigValue) []perror.PulseError {
	return []perror.PulseError{}
}

func (m *mockMetricManager) SubscribePublisher(name string, ver int, config map[string]ctypes.ConfigValue) []perror.PulseError {
	return []perror.PulseError{}
}

func (m *mockMetricManager) Subscribe(mts []core.Metric, prs []core.SubscribedPlugin, pus []core.SubscribedPlugin) []perror.PulseError {
	if m.failValidatingMetrics {
		return []perror.PulseError{
			perror.New(errors.New("metric validation error")),
		}
	}
	return nil
}

func (m *mockMetricManager) UnsubscribePublisher(name string, ver int) error {
	return nil
}

func (m *mockMetricManager) UnsubscribeProcessor(name string, ver int) error {
	return nil
}

type mockMetricManagerError struct {
	errs []error
}

type mockMetricType struct {
	version            int
	namespace          []string
	lastAdvertisedTime time.Time
	config             *cdata.ConfigDataNode
}

func (m mockMetricType) Version() int {
	return m.version
}

func (m mockMetricType) Namespace() []string {
	return m.namespace
}

func (m mockMetricType) LastAdvertisedTime() time.Time {
	return m.lastAdvertisedTime
}

func (m mockMetricType) Config() *cdata.ConfigDataNode {
	return m.config
}

func (m mockMetricType) Data() interface{} {
	return nil
}

type mockScheduleResponse struct {
}

func (m mockScheduleResponse) state() schedule.ScheduleState {
	return schedule.Active
}

func (m mockScheduleResponse) err() error {
	return nil
}

func (m mockScheduleResponse) missedIntervals() uint {
	return 0
}

func TestScheduler(t *testing.T) {
	log.SetLevel(log.FatalLevel)
	Convey("NewTask", t, func() {
		c := new(mockMetricManager)
		c.setAcceptedContentType("machine", core.ProcessorPluginType, 1, []string{"pulse.*", "pulse.gob", "foo.bar"})
		c.setReturnedContentType("machine", core.ProcessorPluginType, 1, []string{"pulse.gob"})
		c.setAcceptedContentType("rmq", core.PublisherPluginType, -1, []string{"pulse.json", "pulse.gob"})
		c.setAcceptedContentType("file", core.PublisherPluginType, -1, []string{"pulse.json"})
		s := New()
		s.SetMetricManager(c)
		w := wmap.NewWorkflowMap()
		// Collection node
		w.CollectNode.AddMetric("/foo/bar", 1)
		w.CollectNode.AddMetric("/foo/baz", 2)
		w.CollectNode.AddConfigItem("/foo/bar", "username", "root")
		w.CollectNode.AddConfigItem("/foo/bar", "port", 8080)
		w.CollectNode.AddConfigItem("/foo/bar", "ratio", 0.32)
		w.CollectNode.AddConfigItem("/foo/bar", "yesorno", true)

		// Add a process node
		pr1 := wmap.NewProcessNode("machine", 1)
		pr1.AddConfigItem("username", "wat")
		pr1.AddConfigItem("howmuch", 9999)

		// Add a process node
		pr12 := wmap.NewProcessNode("machine", 1)
		pr12.AddConfigItem("username", "wat2")
		pr12.AddConfigItem("howmuch", 99992)

		// Publish node for our process node
		pu1 := wmap.NewPublishNode("rmq", -1)
		pu1.AddConfigItem("birthplace", "dallas")
		pu1.AddConfigItem("monies", 2)

		// Publish node direct to collection
		pu2 := wmap.NewPublishNode("file", -1)
		pu2.AddConfigItem("color", "brown")
		pu2.AddConfigItem("purpose", 42)

		pr12.Add(pu2)
		pr1.Add(pr12)
		w.CollectNode.Add(pr1)
		w.CollectNode.Add(pu1)

		e := s.Start()
		So(e, ShouldBeNil)
		t, te := s.CreateTask(schedule.NewSimpleSchedule(time.Second*1), w)
		So(te.Errors(), ShouldBeEmpty)

		for _, i := range t.(*task).workflow.processNodes {
			testInboundContentType(i)
		}
		for _, i := range t.(*task).workflow.publishNodes {
			testInboundContentType(i)
		}
		So(t.(*task).workflow.processNodes[0].ProcessNodes[0].PublishNodes[0].InboundContentType, ShouldEqual, "pulse.json")

		Convey("returns errors when metrics do not validate", func() {
			c.failValidatingMetrics = true
			c.failValidatingMetricsAfter = 1
			_, err := s.CreateTask(schedule.NewSimpleSchedule(time.Second*1), w)
			So(err, ShouldNotBeNil)
			fmt.Printf("%d", len(err.Errors()))
			So(len(err.Errors()), ShouldBeGreaterThan, 0)
			So(err.Errors()[0], ShouldResemble, perror.New(errors.New("metric validation error")))

		})

		Convey("returns an error when scheduler started and MetricManager is not set", func() {
			s1 := New()
			err := s1.Start()
			So(err, ShouldNotBeNil)
			fmt.Printf("%v", err)
			So(err, ShouldResemble, ErrMetricManagerNotSet)

		})

		Convey("returns an error when wrong namespace is given wo workflowmap ", func() {
			w.CollectNode.AddMetric("****/&&&", 3)
			w.CollectNode.AddConfigItem("****/&&&", "username", "user")
			_, err := s.CreateTask(schedule.NewSimpleSchedule(time.Second*1), w)

			So(len(err.Errors()), ShouldBeGreaterThan, 0)

		})

		// TODO NICK
		Convey("returns an error when a schedule does not validate", func() {
			s1 := New()
			s1.Start()
			_, err := s1.CreateTask(schedule.NewSimpleSchedule(time.Second*1), w)
			So(err, ShouldNotBeNil)
			So(len(err.Errors()), ShouldBeGreaterThan, 0)
			So(err.Errors()[0], ShouldResemble, perror.New(ErrSchedulerNotStarted))
			s1.metricManager = c
			s1.Start()
			_, err1 := s1.CreateTask(schedule.NewSimpleSchedule(time.Second*0), w)
			So(err1.Errors()[0], ShouldResemble, perror.New(errors.New("Simple Schedule interval must be greater than 0")))

		})

		// 		// TODO NICK
		Convey("create a task", func() {

			tsk, err := s.CreateTask(schedule.NewSimpleSchedule(time.Second*5), w)
			So(len(err.Errors()), ShouldEqual, 0)
			So(tsk, ShouldNotBeNil)
			So(tsk.(*task).deadlineDuration, ShouldResemble, DefaultDeadlineDuration)
			So(len(s.GetTasks()), ShouldEqual, 2)
			Convey("error when attempting to add duplicate task", func() {
				err := s.tasks.add(tsk.(*task))
				So(err, ShouldNotBeNil)

			})
			Convey("get created task", func() {
				t, err := s.GetTask(tsk.ID())
				So(err, ShouldBeNil)
				So(t, ShouldEqual, tsk)
			})
			Convey("error when attempting to get a task that doesn't exist", func() {
				t, err := s.GetTask(uint64(1234))
				So(err, ShouldNotBeNil)
				So(t, ShouldBeNil)
			})
		})

		// 		// // TODO NICK
		Convey("returns a task with a 6 second deadline duration", func() {
			tsk, err := s.CreateTask(schedule.NewSimpleSchedule(time.Second*6), w, core.TaskDeadlineDuration(6*time.Second))
			So(len(err.Errors()), ShouldEqual, 0)
			So(tsk.(*task).deadlineDuration, ShouldResemble, time.Duration(6*time.Second))
			prev := tsk.(*task).Option(core.TaskDeadlineDuration(1 * time.Second))
			So(tsk.(*task).deadlineDuration, ShouldResemble, time.Duration(1*time.Second))
			tsk.(*task).Option(prev)
			So(tsk.(*task).deadlineDuration, ShouldResemble, time.Duration(6*time.Second))
		})
	})
	Convey("Stop()", t, func() {
		Convey("Should set scheduler state to SchedulerStopped", func() {
			scheduler := New()
			c := new(mockMetricManager)
			scheduler.metricManager = c
			scheduler.Start()
			scheduler.Stop()
			So(scheduler.state, ShouldEqual, schedulerStopped)
		})
	})
	Convey("SetMetricManager()", t, func() {
		Convey("Should set metricManager for scheduler", func() {
			scheduler := New()
			c := new(mockMetricManager)
			scheduler.SetMetricManager(c)
			So(scheduler.metricManager, ShouldEqual, c)
		})
	})

}

func testInboundContentType(node interface{}) {
	switch t := node.(type) {
	case *processNode:
		fmt.Printf("testing content type for pr plugin %s %d/n", t.Name(), t.Version())
		So(t.InboundContentType, ShouldNotEqual, "")
		for _, i := range t.ProcessNodes {
			testInboundContentType(i)
		}
	case *publishNode:
		fmt.Printf("testing content type for pu plugin %s %d/n", t.Name(), t.Version())
		So(t.InboundContentType, ShouldNotEqual, "")
	}
}
<commit_msg>Fixes a test referencing a perror incorrectly<commit_after>package scheduler

import (
	"errors"
	"fmt"
	"testing"
	"time"

	log "github.com/Sirupsen/logrus"
	. "github.com/smartystreets/goconvey/convey"

	"github.com/intelsdi-x/pulse/core"
	"github.com/intelsdi-x/pulse/core/cdata"
	"github.com/intelsdi-x/pulse/core/ctypes"
	"github.com/intelsdi-x/pulse/core/perror"
	"github.com/intelsdi-x/pulse/pkg/schedule"
	"github.com/intelsdi-x/pulse/scheduler/wmap"
)

type mockMetricManager struct {
	failValidatingMetrics      bool
	failValidatingMetricsAfter int
	failuredSoFar              int
	acceptedContentTypes       map[string][]string
	returnedContentTypes       map[string][]string
}

func (m *mockMetricManager) SubscribeMetricType(mt core.RequestedMetric, cd *cdata.ConfigDataNode) (core.Metric, []perror.PulseError) {
	if m.failValidatingMetrics {
		if m.failValidatingMetricsAfter > m.failuredSoFar {
			m.failuredSoFar++
			return nil, nil
		}
		return nil, []perror.PulseError{
			perror.New(errors.New("metric validation error")),
		}
	}
	return nil, nil
}

func (m *mockMetricManager) lazyContentType(key string) {
	if m.acceptedContentTypes == nil {
		m.acceptedContentTypes = make(map[string][]string)
	}
	if m.returnedContentTypes == nil {
		m.returnedContentTypes = make(map[string][]string)
	}
	if m.acceptedContentTypes[key] == nil {
		m.acceptedContentTypes[key] = []string{}
	}
	if m.returnedContentTypes[key] == nil {
		m.returnedContentTypes[key] = []string{}
	}
}

// Used to mock type from plugin
func (m *mockMetricManager) setAcceptedContentType(n string, t core.PluginType, v int, s []string) {
	key := fmt.Sprintf("%s:%d:%d", n, t, v)
	m.lazyContentType(key)
	m.acceptedContentTypes[key] = s
}

func (m *mockMetricManager) setReturnedContentType(n string, t core.PluginType, v int, s []string) {
	key := fmt.Sprintf("%s:%d:%d", n, t, v)
	m.lazyContentType(key)
	m.returnedContentTypes[key] = s
}

func (m *mockMetricManager) GetPluginContentTypes(n string, t core.PluginType, v int) ([]string, []string, error) {
	key := fmt.Sprintf("%s:%d:%d", n, t, v)
	m.lazyContentType(key)

	return m.acceptedContentTypes[key], m.returnedContentTypes[key], nil
}

func (m *mockMetricManager) UnsubscribeMetricType(mt core.Metric) {

}

func (m *mockMetricManager) CollectMetrics([]core.Metric, time.Time) ([]core.Metric, []error) {
	return nil, nil
}

func (m *mockMetricManager) PublishMetrics(contentType string, content []byte, pluginName string, pluginVersion int, config map[string]ctypes.ConfigValue) []error {
	return nil
}

func (m *mockMetricManager) ProcessMetrics(contentType string, content []byte, pluginName string, pluginVersion int, config map[string]ctypes.ConfigValue) (string, []byte, []error) {
	return "", nil, nil
}

func (m *mockMetricManager) SubscribeProcessor(name string, ver int, config map[string]ctypes.ConfigValue) []perror.PulseError {
	return []perror.PulseError{}
}

func (m *mockMetricManager) SubscribePublisher(name string, ver int, config map[string]ctypes.ConfigValue) []perror.PulseError {
	return []perror.PulseError{}
}

func (m *mockMetricManager) Subscribe(mts []core.Metric, prs []core.SubscribedPlugin, pus []core.SubscribedPlugin) []perror.PulseError {
	if m.failValidatingMetrics {
		return []perror.PulseError{
			perror.New(errors.New("metric validation error")),
		}
	}
	return nil
}

func (m *mockMetricManager) UnsubscribePublisher(name string, ver int) error {
	return nil
}

func (m *mockMetricManager) UnsubscribeProcessor(name string, ver int) error {
	return nil
}

type mockMetricManagerError struct {
	errs []error
}

type mockMetricType struct {
	version            int
	namespace          []string
	lastAdvertisedTime time.Time
	config             *cdata.ConfigDataNode
}

func (m mockMetricType) Version() int {
	return m.version
}

func (m mockMetricType) Namespace() []string {
	return m.namespace
}

func (m mockMetricType) LastAdvertisedTime() time.Time {
	return m.lastAdvertisedTime
}

func (m mockMetricType) Config() *cdata.ConfigDataNode {
	return m.config
}

func (m mockMetricType) Data() interface{} {
	return nil
}

type mockScheduleResponse struct {
}

func (m mockScheduleResponse) state() schedule.ScheduleState {
	return schedule.Active
}

func (m mockScheduleResponse) err() error {
	return nil
}

func (m mockScheduleResponse) missedIntervals() uint {
	return 0
}

func TestScheduler(t *testing.T) {
	log.SetLevel(log.FatalLevel)
	Convey("NewTask", t, func() {
		c := new(mockMetricManager)
		c.setAcceptedContentType("machine", core.ProcessorPluginType, 1, []string{"pulse.*", "pulse.gob", "foo.bar"})
		c.setReturnedContentType("machine", core.ProcessorPluginType, 1, []string{"pulse.gob"})
		c.setAcceptedContentType("rmq", core.PublisherPluginType, -1, []string{"pulse.json", "pulse.gob"})
		c.setAcceptedContentType("file", core.PublisherPluginType, -1, []string{"pulse.json"})
		s := New()
		s.SetMetricManager(c)
		w := wmap.NewWorkflowMap()
		// Collection node
		w.CollectNode.AddMetric("/foo/bar", 1)
		w.CollectNode.AddMetric("/foo/baz", 2)
		w.CollectNode.AddConfigItem("/foo/bar", "username", "root")
		w.CollectNode.AddConfigItem("/foo/bar", "port", 8080)
		w.CollectNode.AddConfigItem("/foo/bar", "ratio", 0.32)
		w.CollectNode.AddConfigItem("/foo/bar", "yesorno", true)

		// Add a process node
		pr1 := wmap.NewProcessNode("machine", 1)
		pr1.AddConfigItem("username", "wat")
		pr1.AddConfigItem("howmuch", 9999)

		// Add a process node
		pr12 := wmap.NewProcessNode("machine", 1)
		pr12.AddConfigItem("username", "wat2")
		pr12.AddConfigItem("howmuch", 99992)

		// Publish node for our process node
		pu1 := wmap.NewPublishNode("rmq", -1)
		pu1.AddConfigItem("birthplace", "dallas")
		pu1.AddConfigItem("monies", 2)

		// Publish node direct to collection
		pu2 := wmap.NewPublishNode("file", -1)
		pu2.AddConfigItem("color", "brown")
		pu2.AddConfigItem("purpose", 42)

		pr12.Add(pu2)
		pr1.Add(pr12)
		w.CollectNode.Add(pr1)
		w.CollectNode.Add(pu1)

		e := s.Start()
		So(e, ShouldBeNil)
		t, te := s.CreateTask(schedule.NewSimpleSchedule(time.Second*1), w)
		So(te.Errors(), ShouldBeEmpty)

		for _, i := range t.(*task).workflow.processNodes {
			testInboundContentType(i)
		}
		for _, i := range t.(*task).workflow.publishNodes {
			testInboundContentType(i)
		}
		So(t.(*task).workflow.processNodes[0].ProcessNodes[0].PublishNodes[0].InboundContentType, ShouldEqual, "pulse.json")

		Convey("returns errors when metrics do not validate", func() {
			c.failValidatingMetrics = true
			c.failValidatingMetricsAfter = 1
			_, err := s.CreateTask(schedule.NewSimpleSchedule(time.Second*1), w)
			So(err, ShouldNotBeNil)
			fmt.Printf("%d", len(err.Errors()))
			So(len(err.Errors()), ShouldBeGreaterThan, 0)
			So(err.Errors()[0], ShouldResemble, perror.New(errors.New("metric validation error")))

		})

		Convey("returns an error when scheduler started and MetricManager is not set", func() {
			s1 := New()
			err := s1.Start()
			So(err, ShouldNotBeNil)
			fmt.Printf("%v", err)
			So(err, ShouldResemble, ErrMetricManagerNotSet)

		})

		Convey("returns an error when wrong namespace is given wo workflowmap ", func() {
			w.CollectNode.AddMetric("****/&&&", 3)
			w.CollectNode.AddConfigItem("****/&&&", "username", "user")
			_, err := s.CreateTask(schedule.NewSimpleSchedule(time.Second*1), w)

			So(len(err.Errors()), ShouldBeGreaterThan, 0)

		})

		// TODO NICK
		Convey("returns an error when a schedule does not validate", func() {
			s1 := New()
			s1.Start()
			_, err := s1.CreateTask(schedule.NewSimpleSchedule(time.Second*1), w)
			So(err, ShouldNotBeNil)
			So(len(err.Errors()), ShouldBeGreaterThan, 0)
			So(err.Errors()[0], ShouldResemble, perror.New(ErrSchedulerNotStarted))
			s1.metricManager = c
			s1.Start()
			_, err1 := s1.CreateTask(schedule.NewSimpleSchedule(time.Second*0), w)
			So(err1.Errors()[0].Error(), ShouldResemble, "Interval must be greater than 0")

		})

		// 		// TODO NICK
		Convey("create a task", func() {

			tsk, err := s.CreateTask(schedule.NewSimpleSchedule(time.Second*5), w)
			So(len(err.Errors()), ShouldEqual, 0)
			So(tsk, ShouldNotBeNil)
			So(tsk.(*task).deadlineDuration, ShouldResemble, DefaultDeadlineDuration)
			So(len(s.GetTasks()), ShouldEqual, 2)
			Convey("error when attempting to add duplicate task", func() {
				err := s.tasks.add(tsk.(*task))
				So(err, ShouldNotBeNil)

			})
			Convey("get created task", func() {
				t, err := s.GetTask(tsk.ID())
				So(err, ShouldBeNil)
				So(t, ShouldEqual, tsk)
			})
			Convey("error when attempting to get a task that doesn't exist", func() {
				t, err := s.GetTask(uint64(1234))
				So(err, ShouldNotBeNil)
				So(t, ShouldBeNil)
			})
		})

		// 		// // TODO NICK
		Convey("returns a task with a 6 second deadline duration", func() {
			tsk, err := s.CreateTask(schedule.NewSimpleSchedule(time.Second*6), w, core.TaskDeadlineDuration(6*time.Second))
			So(len(err.Errors()), ShouldEqual, 0)
			So(tsk.(*task).deadlineDuration, ShouldResemble, time.Duration(6*time.Second))
			prev := tsk.(*task).Option(core.TaskDeadlineDuration(1 * time.Second))
			So(tsk.(*task).deadlineDuration, ShouldResemble, time.Duration(1*time.Second))
			tsk.(*task).Option(prev)
			So(tsk.(*task).deadlineDuration, ShouldResemble, time.Duration(6*time.Second))
		})
	})
	Convey("Stop()", t, func() {
		Convey("Should set scheduler state to SchedulerStopped", func() {
			scheduler := New()
			c := new(mockMetricManager)
			scheduler.metricManager = c
			scheduler.Start()
			scheduler.Stop()
			So(scheduler.state, ShouldEqual, schedulerStopped)
		})
	})
	Convey("SetMetricManager()", t, func() {
		Convey("Should set metricManager for scheduler", func() {
			scheduler := New()
			c := new(mockMetricManager)
			scheduler.SetMetricManager(c)
			So(scheduler.metricManager, ShouldEqual, c)
		})
	})

}

func testInboundContentType(node interface{}) {
	switch t := node.(type) {
	case *processNode:
		fmt.Printf("testing content type for pr plugin %s %d/n", t.Name(), t.Version())
		So(t.InboundContentType, ShouldNotEqual, "")
		for _, i := range t.ProcessNodes {
			testInboundContentType(i)
		}
	case *publishNode:
		fmt.Printf("testing content type for pu plugin %s %d/n", t.Name(), t.Version())
		So(t.InboundContentType, ShouldNotEqual, "")
	}
}
<|endoftext|>


<commit_before>package datatype

/*
#cgo pkg-config: libqrencode
#include <stdlib.h>
#include <qrencode.h>
*/
import "C"

import "unsafe"

var origList *C.QRcode_List
var qrcodeList *C.QRcode_List
var qrcode *QRcode

// CreateQRCodes creates multiple QR Codes using structured append
func CreateQRCodes(data []byte) {
	qrcodeList = C.QRcode_encodeDataStructured(C.int(len(data)), (*C.uchar)(unsafe.Pointer(&data[0])), C.int(40), C.QR_ECLEVEL_L)
	origList = qrcodeList
}

// Next increments QRcode_List pointer to the next element
func Next() {
	qrcodeList = (*C.QRcode_List)(qrcodeList.next)
	qrcode = nil
	Code()
}

// Code returns a QRcode struct of the QR Code
func Code() *QRcode {
	if qrcodeList == nil {
		return nil
	}

	if qrcode == nil {
		qrcode = CreateQRCode(qrcodeList.code)
	}

	return qrcode
}

// Size returns the size of the QR Code List
func Size() int {
	return int(C.QRcode_List_size(qrcodeList))
}

// Free frees the QR Code List
func Free() {
	C.QRcode_List_free(origList)
}
<commit_msg>Split data and recursively add to list if data is too large<commit_after>package datatype

/*
#cgo pkg-config: libqrencode
#include <stdlib.h>
#include <qrencode.h>
*/
import "C"

import (
	"syscall"
	"unsafe"
)

var origList *C.QRcode_List
var qrcodeList *C.QRcode_List
var qrcode *QRcode

// CreateQRCodes creates multiple QR Codes using structured append
func CreateQRCodes(data []byte) {
	a, err := C.QRcode_encodeDataStructured(C.int(len(data)), (*C.uchar)(unsafe.Pointer(&data[0])), C.int(40), C.QR_ECLEVEL_L)

	// If data too large
	if err == syscall.ERANGE {
		split(data)
	} else {
		qrcodeList = a
		origList = qrcodeList
	}
}

// Split list and recursively build onto a new one
func split(data []byte) {
	size := len(data) / 2
	var mainList *C.QRcode_List
	CreateQRCodes(data[:size])
	mainList = qrcodeList
	tempList := mainList

	CreateQRCodes(data[size-1 : len(data)])
	for tempList.next != nil {
		tempList = (*C.QRcode_List)(tempList.next)
	}
	for qrcodeList != nil {
		tempList.next = qrcodeList.next
		tempList = (*C.QRcode_List)(tempList.next)
		qrcodeList = (*C.QRcode_List)(qrcodeList.next)
	}
	qrcodeList = mainList
	origList = mainList
}

// Next increments QRcode_List pointer to the next element
func Next() {
	qrcodeList = (*C.QRcode_List)(qrcodeList.next)
	qrcode = nil
	Code()
}

// Code returns a QRcode struct of the QR Code
func Code() *QRcode {
	if qrcodeList == nil {
		return nil
	}

	if qrcode == nil {
		qrcode = CreateQRCode(qrcodeList.code)
	}

	return qrcode
}

// Size returns the size of the QR Code List
func Size() int {
	return int(C.QRcode_List_size(qrcodeList))
}

// Free frees the QR Code List
func Free() {
	C.QRcode_List_free(origList)
}
<|endoftext|>


<commit_before>package neutrino

import (
	"github.com/btcsuite/btcd/addrmgr"
	"github.com/btcsuite/btcd/blockchain"
	"github.com/btcsuite/btcd/peer"
	"github.com/btcsuite/btcd/txscript"
	"github.com/btcsuite/btclog"
	"github.com/lightninglabs/neutrino/blockntfns"
	"github.com/lightninglabs/neutrino/pushtx"
)

// log is a logger that is initialized with no output filters.  This
// means the package will not perform any logging by default until the caller
// requests it.
var log btclog.Logger

// The default amount of logging is none.
func init() {
	DisableLog()
}

// DisableLog disables all library log output.  Logging output is disabled
// by default until either UseLogger or SetLogWriter are called.
func DisableLog() {
	log = btclog.Disabled
}

// UseLogger uses a specified Logger to output package logging info.
// This should be used in preference to SetLogWriter if the caller is also
// using btclog.
func UseLogger(logger btclog.Logger) {
	log = logger
	blockchain.UseLogger(logger)
	txscript.UseLogger(logger)
	peer.UseLogger(logger)
	addrmgr.UseLogger(logger)
	blockntfns.UseLogger(logger)
	pushtx.UseLogger(logger)
}

// logClosure is used to provide a closure over expensive logging operations so
// don't have to be performed when the logging level doesn't warrant it.
type logClosure func() string

// String invokes the underlying function and returns the result.
func (c logClosure) String() string {
	return c()
}

// newLogClosure returns a new closure over a function that returns a string
// which itself provides a Stringer interface so that it can be used with the
// logging system.
func newLogClosure(c func() string) logClosure {
	return logClosure(c)
}
<commit_msg>log: show connmgr logger as part of neutrino logger<commit_after>package neutrino

import (
	"github.com/btcsuite/btcd/addrmgr"
	"github.com/btcsuite/btcd/blockchain"
	"github.com/btcsuite/btcd/connmgr"
	"github.com/btcsuite/btcd/peer"
	"github.com/btcsuite/btcd/txscript"
	"github.com/btcsuite/btclog"
	"github.com/lightninglabs/neutrino/blockntfns"
	"github.com/lightninglabs/neutrino/pushtx"
)

// log is a logger that is initialized with no output filters.  This
// means the package will not perform any logging by default until the caller
// requests it.
var log btclog.Logger

// The default amount of logging is none.
func init() {
	DisableLog()
}

// DisableLog disables all library log output.  Logging output is disabled
// by default until either UseLogger or SetLogWriter are called.
func DisableLog() {
	log = btclog.Disabled
}

// UseLogger uses a specified Logger to output package logging info.
// This should be used in preference to SetLogWriter if the caller is also
// using btclog.
func UseLogger(logger btclog.Logger) {
	log = logger
	blockchain.UseLogger(logger)
	txscript.UseLogger(logger)
	peer.UseLogger(logger)
	addrmgr.UseLogger(logger)
	blockntfns.UseLogger(logger)
	pushtx.UseLogger(logger)
	connmgr.UseLogger(logger)
}

// logClosure is used to provide a closure over expensive logging operations so
// don't have to be performed when the logging level doesn't warrant it.
type logClosure func() string

// String invokes the underlying function and returns the result.
func (c logClosure) String() string {
	return c()
}

// newLogClosure returns a new closure over a function that returns a string
// which itself provides a Stringer interface so that it can be used with the
// logging system.
func newLogClosure(c func() string) logClosure {
	return logClosure(c)
}
<|endoftext|>


<commit_before>package gou

import (
	"fmt"
	"log"
	"os"
	"runtime"
	"strings"
)

const (
	NOLOGGING = -1
	FATAL     = 0
	ERROR     = 1
	WARN      = 2
	INFO      = 3
	DEBUG     = 4
)

/*
https://github.com/mewkiz/pkg/tree/master/term
RED = '\033[0;1;31m'
GREEN = '\033[0;1;32m'
YELLOW = '\033[0;1;33m'
BLUE = '\033[0;1;34m'
MAGENTA = '\033[0;1;35m'
CYAN = '\033[0;1;36m'
WHITE = '\033[0;1;37m'
DARK_MAGENTA = '\033[0;35m'
ANSI_RESET = '\033[0m'
LogColor         = map[int]string{FATAL: "\033[0m\033[37m",
	ERROR: "\033[0m\033[31m",
	WARN:  "\033[0m\033[33m",
	INFO:  "\033[0m\033[32m",
	DEBUG: "\033[0m\033[34m"}

\e]PFdedede
*/

var (
	LogLevel    int = ERROR
	EMPTY       struct{}
	ErrLogLevel int = ERROR
	logger      *log.Logger
	loggerErr   *log.Logger
	LogColor    = map[int]string{FATAL: "\033[0m\033[37m",
		ERROR: "\033[0m\033[31m",
		WARN:  "\033[0m\033[33m",
		INFO:  "\033[0m\033[35m",
		DEBUG: "\033[0m\033[34m"}
	LogPrefix = map[int]string{
		FATAL: "[FATAL] ",
		ERROR: "[ERROR] ",
		WARN:  "[WARN] ",
		INFO:  "[INFO] ",
		DEBUG: "[DEBUG] ",
	}
	postFix                      = "" //\033[0m
	LogLevelWords map[string]int = map[string]int{"fatal": 0, "error": 1, "warn": 2, "info": 3, "debug": 4, "none": -1}
)

// Setup default logging to Stderr, equivalent to:
//
//	gou.SetLogger(log.New(os.Stderr, "", log.Ltime|log.Lshortfile), "debug")
func SetupLogging(lvl string) {
	SetLogger(log.New(os.Stderr, "", log.LstdFlags|log.Lshortfile|log.Lmicroseconds), strings.ToLower(lvl))
}

// Setup default logging to Stderr, equivalent to:
//
//	gou.SetLogger(log.New(os.Stderr, "", log.LstdFlags|log.Lshortfile|log.Lmicroseconds), level)
func SetupLoggingLong(lvl string) {
	SetLogger(log.New(os.Stderr, "", log.LstdFlags|log.Llongfile|log.Lmicroseconds), strings.ToLower(lvl))
}

// Setup colorized output if this is a terminal
func SetColorIfTerminal() {
	if IsTerminal() {
		SetColorOutput()
	}
}

// Setup colorized output
func SetColorOutput() {
	for lvl, color := range LogColor {
		LogPrefix[lvl] = color
	}
	postFix = "\033[0m"
}

// Setup default log output to go to a dev/null
//
//	log.SetOutput(new(DevNull))
func DiscardStandardLogger() {
	log.SetOutput(new(DevNull))
}

// you can set a logger, and log level,most common usage is:
//
//	gou.SetLogger(log.New(os.Stdout, "", log.LstdFlags), "debug")
//
//  loglevls:   debug, info, warn, error, fatal
// Note, that you can also set a seperate Error Log Level
func SetLogger(l *log.Logger, logLevel string) {
	logger = l
	LogLevelSet(logLevel)
}
func GetLogger() *log.Logger {
	return logger
}

// you can set a logger, and log level.  this is for errors, and assumes
// you are logging to Stderr (seperate from stdout above), allowing you to seperate
// debug&info logging from errors
//
//	gou.SetLogger(log.New(os.Stderr, "", log.LstdFlags), "debug")
//
//  loglevls:   debug, info, warn, error, fatal
func SetErrLogger(l *log.Logger, logLevel string) {
	loggerErr = l
	if lvl, ok := LogLevelWords[logLevel]; ok {
		ErrLogLevel = lvl
	}
}
func GetErrLogger() *log.Logger {
	return logger
}

// sets the log level from a string
func LogLevelSet(levelWord string) {
	if lvl, ok := LogLevelWords[levelWord]; ok {
		LogLevel = lvl
	}
}

// Log at debug level
func Debug(v ...interface{}) {
	if LogLevel >= 4 {
		DoLog(3, DEBUG, fmt.Sprint(v...))
	}
}

// Debug log formatted
func Debugf(format string, v ...interface{}) {
	if LogLevel >= 4 {
		DoLog(3, DEBUG, fmt.Sprintf(format, v...))
	}
}

// Log at info level
func Info(v ...interface{}) {
	if LogLevel >= 3 {
		DoLog(3, INFO, fmt.Sprint(v...))
	}
}

// info log formatted
func Infof(format string, v ...interface{}) {
	if LogLevel >= 3 {
		DoLog(3, INFO, fmt.Sprintf(format, v...))
	}
}

// Log at warn level
func Warn(v ...interface{}) {
	if LogLevel >= 2 {
		DoLog(3, WARN, fmt.Sprint(v...))
	}
}

// Debug log formatted
func Warnf(format string, v ...interface{}) {
	if LogLevel >= 2 {
		DoLog(3, WARN, fmt.Sprintf(format, v...))
	}
}

// Log at error level
func Error(v ...interface{}) {
	if LogLevel >= 1 {
		DoLog(3, ERROR, fmt.Sprint(v...))
	}
}

// Error log formatted
func Errorf(format string, v ...interface{}) {
	if LogLevel >= 1 {
		DoLog(3, ERROR, fmt.Sprintf(format, v...))
	}
}

// Log to logger if setup
//    Log(ERROR, "message")
func Log(logLvl int, v ...interface{}) {
	if LogLevel >= logLvl {
		DoLog(3, logLvl, fmt.Sprint(v...))
	}
}

// Log to logger if setup, grab a stack trace and add that as well
//
//    u.LogTracef(u.ERROR, "message %s", varx)
//
func LogTracef(logLvl int, format string, v ...interface{}) {
	if LogLevel >= logLvl {
		// grab a stack trace
		stackBuf := make([]byte, 4096)
		stackBufLen := runtime.Stack(stackBuf, false)
		stackTraceStr := string(stackBuf[0:stackBufLen])
		v = append(v, stackTraceStr)
		DoLog(5, logLvl, fmt.Sprintf(format+"\n%v", v...))
	}
}

// Log to logger if setup
//    Logf(ERROR, "message %d", 20)
func Logf(logLvl int, format string, v ...interface{}) {
	if LogLevel >= logLvl {
		DoLog(3, logLvl, fmt.Sprintf(format, v...))
	}
}

// Log to logger if setup
//    LogP(ERROR, "prefix", "message", anyItems, youWant)
func LogP(logLvl int, prefix string, v ...interface{}) {
	if ErrLogLevel >= logLvl && loggerErr != nil {
		loggerErr.Output(3, prefix+LogPrefix[logLvl]+fmt.Sprint(v...)+postFix)
	} else if LogLevel >= logLvl && logger != nil {
		logger.Output(3, prefix+LogPrefix[logLvl]+fmt.Sprint(v...)+postFix)
	}
}

// Log to logger if setup with a prefix
//    LogPf(ERROR, "prefix", "formatString %s %v", anyItems, youWant)
func LogPf(logLvl int, prefix string, format string, v ...interface{}) {
	if ErrLogLevel >= logLvl && loggerErr != nil {
		loggerErr.Output(3, prefix+LogPrefix[logLvl]+fmt.Sprintf(format, v...)+postFix)
	} else if LogLevel >= logLvl && logger != nil {
		logger.Output(3, prefix+LogPrefix[logLvl]+fmt.Sprintf(format, v...)+postFix)
	}
}

// When you want to use the log short filename flag, and want to use
// the lower level logging functions (say from an *Assert* type function)
// you need to modify the stack depth:
//
//     func init() {}
// 	       SetLogger(log.New(os.Stderr, "", log.Ltime|log.Lshortfile|log.Lmicroseconds), lvl)
//     }
//
//     func assert(t *testing.T, myData) {
//         // we want log line to show line that called this assert, not this line
//         LogD(5, DEBUG, v...)
//     }
func LogD(depth int, logLvl int, v ...interface{}) {
	if LogLevel >= logLvl {
		DoLog(depth, logLvl, fmt.Sprint(v...))
	}
}

// Low level log with depth , level, message and logger
func DoLog(depth, logLvl int, msg string) {
	if ErrLogLevel >= logLvl && loggerErr != nil {
		loggerErr.Output(depth, LogPrefix[logLvl]+msg+postFix)
	} else if LogLevel >= logLvl && logger != nil {
		logger.Output(depth, LogPrefix[logLvl]+msg+postFix)
	}
}

type winsize struct {
	Row    uint16
	Col    uint16
	Xpixel uint16
	Ypixel uint16
}

const (
	_TIOCGWINSZ = 0x5413 // OSX 1074295912
)

//http://play.golang.org/p/5LIA41Iqfp
// Dummy discard, satisfies io.Writer without importing io or os.
type DevNull struct{}

func (DevNull) Write(p []byte) (int, error) {
	return len(p), nil
}
<commit_msg>chop off gou.Log info from stack trace<commit_after>package gou

import (
	"fmt"
	"log"
	"os"
	"runtime"
	"strings"
)

const (
	NOLOGGING = -1
	FATAL     = 0
	ERROR     = 1
	WARN      = 2
	INFO      = 3
	DEBUG     = 4
)

/*
https://github.com/mewkiz/pkg/tree/master/term
RED = '\033[0;1;31m'
GREEN = '\033[0;1;32m'
YELLOW = '\033[0;1;33m'
BLUE = '\033[0;1;34m'
MAGENTA = '\033[0;1;35m'
CYAN = '\033[0;1;36m'
WHITE = '\033[0;1;37m'
DARK_MAGENTA = '\033[0;35m'
ANSI_RESET = '\033[0m'
LogColor         = map[int]string{FATAL: "\033[0m\033[37m",
	ERROR: "\033[0m\033[31m",
	WARN:  "\033[0m\033[33m",
	INFO:  "\033[0m\033[32m",
	DEBUG: "\033[0m\033[34m"}

\e]PFdedede
*/

var (
	LogLevel    int = ERROR
	EMPTY       struct{}
	ErrLogLevel int = ERROR
	logger      *log.Logger
	loggerErr   *log.Logger
	LogColor    = map[int]string{FATAL: "\033[0m\033[37m",
		ERROR: "\033[0m\033[31m",
		WARN:  "\033[0m\033[33m",
		INFO:  "\033[0m\033[35m",
		DEBUG: "\033[0m\033[34m"}
	LogPrefix = map[int]string{
		FATAL: "[FATAL] ",
		ERROR: "[ERROR] ",
		WARN:  "[WARN] ",
		INFO:  "[INFO] ",
		DEBUG: "[DEBUG] ",
	}
	postFix                      = "" //\033[0m
	LogLevelWords map[string]int = map[string]int{"fatal": 0, "error": 1, "warn": 2, "info": 3, "debug": 4, "none": -1}
)

// Setup default logging to Stderr, equivalent to:
//
//	gou.SetLogger(log.New(os.Stderr, "", log.Ltime|log.Lshortfile), "debug")
func SetupLogging(lvl string) {
	SetLogger(log.New(os.Stderr, "", log.LstdFlags|log.Lshortfile|log.Lmicroseconds), strings.ToLower(lvl))
}

// Setup default logging to Stderr, equivalent to:
//
//	gou.SetLogger(log.New(os.Stderr, "", log.LstdFlags|log.Lshortfile|log.Lmicroseconds), level)
func SetupLoggingLong(lvl string) {
	SetLogger(log.New(os.Stderr, "", log.LstdFlags|log.Llongfile|log.Lmicroseconds), strings.ToLower(lvl))
}

// Setup colorized output if this is a terminal
func SetColorIfTerminal() {
	if IsTerminal() {
		SetColorOutput()
	}
}

// Setup colorized output
func SetColorOutput() {
	for lvl, color := range LogColor {
		LogPrefix[lvl] = color
	}
	postFix = "\033[0m"
}

// Setup default log output to go to a dev/null
//
//	log.SetOutput(new(DevNull))
func DiscardStandardLogger() {
	log.SetOutput(new(DevNull))
}

// you can set a logger, and log level,most common usage is:
//
//	gou.SetLogger(log.New(os.Stdout, "", log.LstdFlags), "debug")
//
//  loglevls:   debug, info, warn, error, fatal
// Note, that you can also set a seperate Error Log Level
func SetLogger(l *log.Logger, logLevel string) {
	logger = l
	LogLevelSet(logLevel)
}
func GetLogger() *log.Logger {
	return logger
}

// you can set a logger, and log level.  this is for errors, and assumes
// you are logging to Stderr (seperate from stdout above), allowing you to seperate
// debug&info logging from errors
//
//	gou.SetLogger(log.New(os.Stderr, "", log.LstdFlags), "debug")
//
//  loglevls:   debug, info, warn, error, fatal
func SetErrLogger(l *log.Logger, logLevel string) {
	loggerErr = l
	if lvl, ok := LogLevelWords[logLevel]; ok {
		ErrLogLevel = lvl
	}
}
func GetErrLogger() *log.Logger {
	return logger
}

// sets the log level from a string
func LogLevelSet(levelWord string) {
	if lvl, ok := LogLevelWords[levelWord]; ok {
		LogLevel = lvl
	}
}

// Log at debug level
func Debug(v ...interface{}) {
	if LogLevel >= 4 {
		DoLog(3, DEBUG, fmt.Sprint(v...))
	}
}

// Debug log formatted
func Debugf(format string, v ...interface{}) {
	if LogLevel >= 4 {
		DoLog(3, DEBUG, fmt.Sprintf(format, v...))
	}
}

// Log at info level
func Info(v ...interface{}) {
	if LogLevel >= 3 {
		DoLog(3, INFO, fmt.Sprint(v...))
	}
}

// info log formatted
func Infof(format string, v ...interface{}) {
	if LogLevel >= 3 {
		DoLog(3, INFO, fmt.Sprintf(format, v...))
	}
}

// Log at warn level
func Warn(v ...interface{}) {
	if LogLevel >= 2 {
		DoLog(3, WARN, fmt.Sprint(v...))
	}
}

// Debug log formatted
func Warnf(format string, v ...interface{}) {
	if LogLevel >= 2 {
		DoLog(3, WARN, fmt.Sprintf(format, v...))
	}
}

// Log at error level
func Error(v ...interface{}) {
	if LogLevel >= 1 {
		DoLog(3, ERROR, fmt.Sprint(v...))
	}
}

// Error log formatted
func Errorf(format string, v ...interface{}) {
	if LogLevel >= 1 {
		DoLog(3, ERROR, fmt.Sprintf(format, v...))
	}
}

// Log to logger if setup
//    Log(ERROR, "message")
func Log(logLvl int, v ...interface{}) {
	if LogLevel >= logLvl {
		DoLog(3, logLvl, fmt.Sprint(v...))
	}
}

// Log to logger if setup, grab a stack trace and add that as well
//
//    u.LogTracef(u.ERROR, "message %s", varx)
//
func LogTracef(logLvl int, format string, v ...interface{}) {
	if LogLevel >= logLvl {
		// grab a stack trace
		stackBuf := make([]byte, 6000)
		stackBufLen := runtime.Stack(stackBuf, false)
		stackTraceStr := string(stackBuf[0:stackBufLen])
		parts := strings.Split(stackTraceStr, "\n")
		if len(parts) > 1 {
			v = append(v, strings.Join(parts[3:len(parts)], "\n"))
		}
		DoLog(4, logLvl, fmt.Sprintf(format+"\n%v", v...))
	}
}

// Log to logger if setup
//    Logf(ERROR, "message %d", 20)
func Logf(logLvl int, format string, v ...interface{}) {
	if LogLevel >= logLvl {
		DoLog(3, logLvl, fmt.Sprintf(format, v...))
	}
}

// Log to logger if setup
//    LogP(ERROR, "prefix", "message", anyItems, youWant)
func LogP(logLvl int, prefix string, v ...interface{}) {
	if ErrLogLevel >= logLvl && loggerErr != nil {
		loggerErr.Output(3, prefix+LogPrefix[logLvl]+fmt.Sprint(v...)+postFix)
	} else if LogLevel >= logLvl && logger != nil {
		logger.Output(3, prefix+LogPrefix[logLvl]+fmt.Sprint(v...)+postFix)
	}
}

// Log to logger if setup with a prefix
//    LogPf(ERROR, "prefix", "formatString %s %v", anyItems, youWant)
func LogPf(logLvl int, prefix string, format string, v ...interface{}) {
	if ErrLogLevel >= logLvl && loggerErr != nil {
		loggerErr.Output(3, prefix+LogPrefix[logLvl]+fmt.Sprintf(format, v...)+postFix)
	} else if LogLevel >= logLvl && logger != nil {
		logger.Output(3, prefix+LogPrefix[logLvl]+fmt.Sprintf(format, v...)+postFix)
	}
}

// When you want to use the log short filename flag, and want to use
// the lower level logging functions (say from an *Assert* type function)
// you need to modify the stack depth:
//
//     func init() {}
// 	       SetLogger(log.New(os.Stderr, "", log.Ltime|log.Lshortfile|log.Lmicroseconds), lvl)
//     }
//
//     func assert(t *testing.T, myData) {
//         // we want log line to show line that called this assert, not this line
//         LogD(5, DEBUG, v...)
//     }
func LogD(depth int, logLvl int, v ...interface{}) {
	if LogLevel >= logLvl {
		DoLog(depth, logLvl, fmt.Sprint(v...))
	}
}

// Low level log with depth , level, message and logger
func DoLog(depth, logLvl int, msg string) {
	if ErrLogLevel >= logLvl && loggerErr != nil {
		loggerErr.Output(depth, LogPrefix[logLvl]+msg+postFix)
	} else if LogLevel >= logLvl && logger != nil {
		logger.Output(depth, LogPrefix[logLvl]+msg+postFix)
	}
}

type winsize struct {
	Row    uint16
	Col    uint16
	Xpixel uint16
	Ypixel uint16
}

const (
	_TIOCGWINSZ = 0x5413 // OSX 1074295912
)

//http://play.golang.org/p/5LIA41Iqfp
// Dummy discard, satisfies io.Writer without importing io or os.
type DevNull struct{}

func (DevNull) Write(p []byte) (int, error) {
	return len(p), nil
}
<|endoftext|>


<commit_before>package extdirect
import (
	stdlog "log"
	"os"
	"github.com/Sirupsen/logrus"
	"strings"
	"runtime/debug"
)

type logger interface {
	Print(v ...interface{})
}

const (
	logLevelInfo = "info: "
	logLevelWarn = "warn: "
)

var log logger = stdlog.New(os.Stderr, "", stdlog.LstdFlags)

func SetLogger(l logger) {
	log = l
}

type LogrusLogger struct {
	L *logrus.Entry
}
func (this *LogrusLogger) Print(v ...interface{}) {
	if len(v) == 0 {
		return
	}
	l := this.L
	if len(v) == 1 {
		if err, errOk := v[0].(error); errOk {
			if err2, err2Ok := err.(*ErrDirectActionMethod); err2Ok {
				l = l.WithFields(logrus.Fields{
					"action": err2.Action,
					"method": err2.Method,
					"stack": string(debug.Stack()),
				})
			}
			l.Error(err)
		} else {
			l.Debug(v[0])
		}
	} else {
		if len(v) > 2 {
			l = l.WithFields(v[2].(map[string]interface{}))
		}

		m := strings.TrimSpace(v[1].(string))
		switch strings.TrimSpace(v[0].(string)) {
		case logLevelInfo: l.Info(m)
		case logLevelWarn: l.Warn(m)
		}
	}
}<commit_msg>Log level definition fixed.<commit_after>package extdirect
import (
	stdlog "log"
	"os"
	"github.com/Sirupsen/logrus"
	"strings"
	"runtime/debug"
)

type logger interface {
	Print(v ...interface{})
}

const (
	logLevelInfo = "info: "
	logLevelWarn = "warn: "
)

var log logger = stdlog.New(os.Stderr, "", stdlog.LstdFlags)

func SetLogger(l logger) {
	log = l
}

type LogrusLogger struct {
	L *logrus.Entry
}
func (this *LogrusLogger) Print(v ...interface{}) {
	if len(v) == 0 {
		return
	}
	l := this.L
	if len(v) == 1 {
		if err, errOk := v[0].(error); errOk {
			if err2, err2Ok := err.(*ErrDirectActionMethod); err2Ok {
				l = l.WithFields(logrus.Fields{
					"action": err2.Action,
					"method": err2.Method,
					"stack": string(debug.Stack()),
				})
			}
			l.Error(err)
		} else {
			l.Debug(v[0])
		}
	} else {
		if len(v) > 2 {
			l = l.WithFields(v[2].(map[string]interface{}))
		}

		m := strings.TrimSpace(v[1].(string))
		logLevel := v[0].(string)
		switch logLevel {
		case logLevelInfo: l.Info(m)
		case logLevelWarn: l.Warn(m)
		default: stdlog.Panicf("Unknow log message type: '%v'", logLevel)
		}
	}
}<|endoftext|>


<commit_before>package config

import (
	"os/exec"
	"time"
)

// Global system constants
const NumButtons = 3
const NumFloors = 4
const DoorOpenTime = 3 * time.Second

const (
	BtnUp int = iota
	BtnDown
	BtnInside
)

const (
	DirDown int = iota - 1
	DirStop
	DirUp
)

// Local IP address
var Laddr string

type Keypress struct {
	Button int
	Floor  int
}

// Generic network message. No other messages are ever sent on the network.
type Message struct {
	Category int
	Floor    int
	Button   int
	Cost     int
	Addr     string `json:"-"`
}

type Elevator struct {
	floor int
	dirn  int
	behaviour int
}

// Network message category constants
const (
	Alive int = iota + 1
	NewOrder
	CompleteOrder
	Cost
)

var SyncLightsChan = make(chan bool)
var CloseConnectionChan = make(chan bool)

// Start a new terminal when restart.Run()
var Restart = exec.Command("gnome-terminal", "-x", "sh", "-c", "main")

// Colours for printing to console
const Col0 = "\x1b[30;1m" // Dark grey
const ColR = "\x1b[31;1m" // Red
const ColG = "\x1b[32;1m" // Green
const ColY = "\x1b[33;1m" // Yellow
const ColB = "\x1b[34;1m" // Blue
const ColM = "\x1b[35;1m" // Magenta
const ColC = "\x1b[36;1m" // Cyan
const ColW = "\x1b[37;1m" // White
const ColN = "\x1b[0m"    // Grey (neutral)
<commit_msg>fixed definitions<commit_after>package definitions

import (
	"os/exec"
	"time"
)

// Global system constants
const NumButtons = 3
const NumFloors = 4
const DoorOpenTime = 3 * time.Second

const (
	BtnUp int = iota
	BtnDown
	BtnInside
)

const (
	DirDown int = iota - 1
	DirStop
	DirUp
)

// Local IP address
var Laddr string

type Keypress struct {
	Button int
	Floor  int
}

// Generic network message. No other messages are ever sent on the network.
type Message struct {
	Category int
	Floor    int
	Button   int
	Cost     int
	Addr     string `json:"-"`
}

type Elevator struct {
	floor int
	dirn  int
	behaviour int
}

// Network message category constants
const (
	Alive int = iota + 1
	NewOrder
	CompleteOrder
	Cost
)

var SyncLightsChan = make(chan bool)
var CloseConnectionChan = make(chan bool)

// Start a new terminal when restart.Run()
var Restart = exec.Command("gnome-terminal", "-x", "sh", "-c", "main")

// Colours for printing to console
const Col0 = "\x1b[30;1m" // Dark grey
const ColR = "\x1b[31;1m" // Red
const ColG = "\x1b[32;1m" // Green
const ColY = "\x1b[33;1m" // Yellow
const ColB = "\x1b[34;1m" // Blue
const ColM = "\x1b[35;1m" // Magenta
const ColC = "\x1b[36;1m" // Cyan
const ColW = "\x1b[37;1m" // White
const ColN = "\x1b[0m"    // Grey (neutral)
<|endoftext|>


<commit_before>package logentries

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
)

type LogClient struct {
	AccountKey string
}

type LogCreateRequest struct {
	LogSetKey string
	Name      string
	Retention string
	Source    string
	Type      string
	Filename  string
}

type LogCreateResponse struct {
	Key    string `json:"log_key"`
	Worker string `json:"worker"`
	Log    Log    `json:"log"`
	ApiResponse
}

func (l *LogClient) Create(createRequest LogCreateRequest) (*Log, error) {
	form := url.Values{}
	form.Add("request", "new_log")
	form.Add("user_key", l.AccountKey)
	form.Add("host_key", createRequest.LogSetKey)
	form.Add("name", createRequest.Name)
	form.Add("type", createRequest.Type)
	form.Add("filename", createRequest.Filename)
	form.Add("retention", createRequest.Retention)
	form.Add("source", createRequest.Source)
	resp, err := http.PostForm("https://api.logentries.com/", form)

	if err != nil {
		return nil, err
	}

	if resp.StatusCode == 200 {
		var response LogCreateResponse
		json.NewDecoder(resp.Body).Decode(&response)
		if response.Response == "ok" {
			return &response.Log, nil
		} else {
			return nil, fmt.Errorf("failed to create log %s: %s", createRequest.Name, response.ResponseReason)
		}
	}

	body, _ := ioutil.ReadAll(resp.Body)
	return nil, fmt.Errorf("Could not retrieve log %s: %s", createRequest.Name, string(body))
}

type LogReadRequest struct {
	LogSetKey string
	Key       string
}

type LogReadResponse struct {
	Log Log `json:"log"`
	ApiResponse
}

func (l *LogClient) Read(readRequest LogReadRequest) (*Log, error) {
	form := url.Values{}
	form.Add("request", "get_log")
	form.Add("log_key", readRequest.Key)
	resp, err := http.PostForm("https://api.logentries.com/", form)

	if err != nil {
		return nil, err
	}

	if resp.StatusCode == 200 {
		var response LogReadResponse
		json.NewDecoder(resp.Body).Decode(&response)
		if response.Response == "ok" {
			return &response.Log, nil
		} else {
			return nil, fmt.Errorf("failed to get log %s: %s", readRequest.Key, response.ResponseReason)
		}
	}

	body, _ := ioutil.ReadAll(resp.Body)
	return nil, fmt.Errorf("Could not retrieve log %s: %s", readRequest.Key, string(body))
}

type LogUpdateRequest struct {
	Key       string
	Name      string
	Type      string
	Source    string
	Retention string
}

type LogUpdateResponse struct {
	Key    string `json:"log_key"`
	Worker string `json:"worker"`
	Log    Log    `json:"log"`
	ApiResponse
}

func (l *LogClient) Update(updateRequest LogUpdateRequest) (*Log, error) {
	form := url.Values{}
	form.Add("request", "set_log")
	form.Add("user_key", l.AccountKey)
	form.Add("log_key", updateRequest.Key)
	form.Add("name", updateRequest.Name)
	form.Add("type", updateRequest.Type)
	form.Add("source", updateRequest.Source)
	form.Add("retention", string(updateRequest.Retention))
	resp, err := http.PostForm("https://api.logentries.com/", form)

	if err != nil {
		return nil, err
	}

	if resp.StatusCode == 200 {
		var response LogUpdateResponse
		json.NewDecoder(resp.Body).Decode(&response)
		if response.Response == "ok" {
			return &response.Log, nil
		} else {
			return nil, fmt.Errorf("failed to update log %s: %s", updateRequest.Name, response.ResponseReason)
		}
	}

	body, _ := ioutil.ReadAll(resp.Body)
	return nil, fmt.Errorf("Could not retrieve log %s: %s", updateRequest.Name, string(body))
}

type LogDeleteRequest struct {
	LogSetKey string
	Key       string
}

type LogDeleteResponse struct {
	LogSetKey string `json:"host_key"`
	UserKey   string `json:"user_key"`
	Key       string `json:"log_key"`
	Worker    string `json:"worker"`
	ApiResponse
}

func (l *LogClient) Delete(deleteRequest LogDeleteRequest) error {
	form := url.Values{}
	form.Add("request", "rm_log")
	form.Add("user_key", l.AccountKey)
	form.Add("host_key", deleteRequest.LogSetKey)
	form.Add("log_key", deleteRequest.Key)
	resp, err := http.PostForm("https://api.logentries.com/", form)

	if err != nil {
		return err
	}

	if resp.StatusCode == 200 {
		var deleteResponse LogDeleteResponse
		json.NewDecoder(resp.Body).Decode(&deleteResponse)
		if deleteResponse.Response == "ok" {
			return nil
		} else {
			return fmt.Errorf("failed to delete log %s: %s", deleteResponse.Key, deleteResponse.ResponseReason)
		}
	}

	return fmt.Errorf("failed to delete log %s: %s", deleteRequest.Key, resp.Body)
}

func NewLogClient(account_key string) *LogClient {
	log := &LogClient{AccountKey: account_key}
	return log
}
<commit_msg>add log update filename attribute<commit_after>package logentries

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
)

type LogClient struct {
	AccountKey string
}

type LogCreateRequest struct {
	LogSetKey string
	Name      string
	Retention string
	Source    string
	Type      string
	Filename  string
}

type LogCreateResponse struct {
	Key    string `json:"log_key"`
	Worker string `json:"worker"`
	Log    Log    `json:"log"`
	ApiResponse
}

func (l *LogClient) Create(createRequest LogCreateRequest) (*Log, error) {
	form := url.Values{}
	form.Add("request", "new_log")
	form.Add("user_key", l.AccountKey)
	form.Add("host_key", createRequest.LogSetKey)
	form.Add("name", createRequest.Name)
	form.Add("type", createRequest.Type)
	form.Add("filename", createRequest.Filename)
	form.Add("retention", createRequest.Retention)
	form.Add("source", createRequest.Source)
	resp, err := http.PostForm("https://api.logentries.com/", form)

	if err != nil {
		return nil, err
	}

	if resp.StatusCode == 200 {
		var response LogCreateResponse
		json.NewDecoder(resp.Body).Decode(&response)
		if response.Response == "ok" {
			return &response.Log, nil
		} else {
			return nil, fmt.Errorf("failed to create log %s: %s", createRequest.Name, response.ResponseReason)
		}
	}

	body, _ := ioutil.ReadAll(resp.Body)
	return nil, fmt.Errorf("Could not retrieve log %s: %s", createRequest.Name, string(body))
}

type LogReadRequest struct {
	LogSetKey string
	Key       string
}

type LogReadResponse struct {
	Log Log `json:"log"`
	ApiResponse
}

func (l *LogClient) Read(readRequest LogReadRequest) (*Log, error) {
	form := url.Values{}
	form.Add("request", "get_log")
	form.Add("log_key", readRequest.Key)
	resp, err := http.PostForm("https://api.logentries.com/", form)

	if err != nil {
		return nil, err
	}

	if resp.StatusCode == 200 {
		var response LogReadResponse
		json.NewDecoder(resp.Body).Decode(&response)
		if response.Response == "ok" {
			return &response.Log, nil
		} else {
			return nil, fmt.Errorf("failed to get log %s: %s", readRequest.Key, response.ResponseReason)
		}
	}

	body, _ := ioutil.ReadAll(resp.Body)
	return nil, fmt.Errorf("Could not retrieve log %s: %s", readRequest.Key, string(body))
}

type LogUpdateRequest struct {
	Key       string
	Name      string
	Type      string
	Source    string
	Retention string
	Filename  string
}

type LogUpdateResponse struct {
	Key    string `json:"log_key"`
	Worker string `json:"worker"`
	Log    Log    `json:"log"`
	ApiResponse
}

func (l *LogClient) Update(updateRequest LogUpdateRequest) (*Log, error) {
	form := url.Values{}
	form.Add("request", "set_log")
	form.Add("user_key", l.AccountKey)
	form.Add("log_key", updateRequest.Key)
	form.Add("name", updateRequest.Name)
	form.Add("type", updateRequest.Type)
	form.Add("source", updateRequest.Source)
	form.Add("filename", updateRequest.Filename)
	form.Add("retention", updateRequest.Retention)
	resp, err := http.PostForm("https://api.logentries.com/", form)

	if err != nil {
		return nil, err
	}

	if resp.StatusCode == 200 {
		var response LogUpdateResponse
		json.NewDecoder(resp.Body).Decode(&response)
		if response.Response == "ok" {
			return &response.Log, nil
		} else {
			return nil, fmt.Errorf("failed to update log %s: %s", updateRequest.Name, response.ResponseReason)
		}
	}

	body, _ := ioutil.ReadAll(resp.Body)
	return nil, fmt.Errorf("Could not retrieve log %s: %s", updateRequest.Name, string(body))
}

type LogDeleteRequest struct {
	LogSetKey string
	Key       string
}

type LogDeleteResponse struct {
	LogSetKey string `json:"host_key"`
	UserKey   string `json:"user_key"`
	Key       string `json:"log_key"`
	Worker    string `json:"worker"`
	ApiResponse
}

func (l *LogClient) Delete(deleteRequest LogDeleteRequest) error {
	form := url.Values{}
	form.Add("request", "rm_log")
	form.Add("user_key", l.AccountKey)
	form.Add("host_key", deleteRequest.LogSetKey)
	form.Add("log_key", deleteRequest.Key)
	resp, err := http.PostForm("https://api.logentries.com/", form)

	if err != nil {
		return err
	}

	if resp.StatusCode == 200 {
		var deleteResponse LogDeleteResponse
		json.NewDecoder(resp.Body).Decode(&deleteResponse)
		if deleteResponse.Response == "ok" {
			return nil
		} else {
			return fmt.Errorf("failed to delete log %s: %s", deleteResponse.Key, deleteResponse.ResponseReason)
		}
	}

	return fmt.Errorf("failed to delete log %s: %s", deleteRequest.Key, resp.Body)
}

func NewLogClient(account_key string) *LogClient {
	log := &LogClient{AccountKey: account_key}
	return log
}
<|endoftext|>


<commit_before>package main

import (
	log "github.com/Sirupsen/logrus"
	"github.com/codegangsta/cli"
	"github.com/loadimpact/speedboat/client"
	"github.com/loadimpact/speedboat/master"
	"time"
)

func init() {
	registerCommand(cli.Command{
		Name:   "ping",
		Usage:  "Test command, will be removed",
		Action: actionPing,
	})
	registerHandler(handlePing)
}

func handlePing(m *master.Master, msg master.Message, out chan master.Message) bool {
	switch msg.Type {
	case "ping.ping":
		out <- master.Message{
			Type: "ping.pong",
			Body: msg.Body,
		}
		return true
	default:
		return false
	}
}

func actionPing(c *cli.Context) {
	client, err := client.New("tcp://127.0.0.1:9595", "tcp://127.0.0.1:9596")
	if err != nil {
		log.WithError(err).Fatal("Couldn't create a client")
	}

	in, out, errors := client.Connector.Run()
	out <- master.Message{
		Type: "ping.ping",
		Body: time.Now().Format("15:04:05 2006-01-02 MST"),
	}

	select {
	case reply := <-in:
		log.WithFields(log.Fields{
			"type": reply.Type,
			"body": reply.Body,
		}).Info("Reply")
	case err := <-errors:
		log.WithError(err).Error("Ping failed")
	}
}
<commit_msg>Just ignore unknown messages<commit_after>package main

import (
	log "github.com/Sirupsen/logrus"
	"github.com/codegangsta/cli"
	"github.com/loadimpact/speedboat/client"
	"github.com/loadimpact/speedboat/master"
	"time"
)

func init() {
	registerCommand(cli.Command{
		Name:   "ping",
		Usage:  "Test command, will be removed",
		Action: actionPing,
	})
	registerHandler(handlePing)
}

func handlePing(m *master.Master, msg master.Message, out chan master.Message) bool {
	switch msg.Type {
	case "ping.ping":
		out <- master.Message{
			Type: "ping.pong",
			Body: msg.Body,
		}
		return true
	default:
		return false
	}
}

func actionPing(c *cli.Context) {
	client, err := client.New("tcp://127.0.0.1:9595", "tcp://127.0.0.1:9596")
	if err != nil {
		log.WithError(err).Fatal("Couldn't create a client")
	}
	in, out, errors := client.Connector.Run()

	// Send a bunch of noise to filter through
	out <- master.Message{Type: "ping.noise"}
	out <- master.Message{Type: "ping.noise"}

	// Send a ping message, server should reply with a pong
	out <- master.Message{
		Type: "ping.ping",
		Body: time.Now().Format("15:04:05 2006-01-02 MST"),
	}

readLoop:
	for {
		select {
		case msg := <-in:
			switch msg.Type {
			case "ping.pong":
				log.WithFields(log.Fields{
					"body": msg.Body,
				}).Info("Pong!")
				break readLoop
			}
		case err := <-errors:
			log.WithError(err).Error("Ping failed")
		}
	}
}
<|endoftext|>


<commit_before>package homecloud

import (
	"encoding/json"
	"fmt"
	"net/http"

	"github.com/gorilla/websocket"
	"github.com/ninjasphere/go-ninja/api"
	"github.com/ninjasphere/go-ninja/bus"
	"github.com/ninjasphere/go-ninja/config"
	"github.com/ninjasphere/go-ninja/logger"
)

var upgrader = websocket.Upgrader{
	ReadBufferSize:  1024,
	WriteBufferSize: 1024,
	CheckOrigin:     func(r *http.Request) bool { return true },
}

type socketCommand struct {
	Command      string            `json:"command"`
	Topic        string            `json:"topic"`
	Payload      string            `json:"payload"`
	Subscription int               `json:"subscription"`
	Params       map[string]string `json:"params"`
}

type WebsocketServer struct {
	log *logger.Logger
}

func (s *WebsocketServer) PostConstruct() error {
	s.log = logger.GetLogger("WebsocketServer")
	return s.Listen()
}

func (s *WebsocketServer) Listen() error {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {

		log.Debugf("Websocket incoming connection")

		ws, err := upgrader.Upgrade(w, r, nil)
		if err != nil {
			log.Errorf("Websocket upgrade error: %s", err)
			return
		}

		clientID := "websocket-" + r.RemoteAddr
		mqttURL := fmt.Sprintf("%s:%d", config.MustString("mqtt", "host"), config.MustInt("mqtt", "port"))

		log.Infof("Connecting to %s using cid:%s", mqttURL, clientID)

		mqtt := bus.MustConnect(mqttURL, clientID)

		subscriptions := make(map[int]*bus.Subscription)

		send := func(command socketCommand) {
			js, _ := json.Marshal(command)
			if err = ws.WriteMessage(websocket.TextMessage, js); err != nil {
				log.Errorf("Websocket failed writing message error: %s", err)
			}
		}

		id := 0

		go func() {
			for {
				_, p, err := ws.ReadMessage()
				if err != nil {
					mqtt.Destroy()
					return
				}

				var cmd socketCommand
				err = json.Unmarshal(p, &cmd)

				log.Debugf("Incoming ws message: %s", p)

				if cmd.Command == "unsubscribe" {
					sub, ok := subscriptions[cmd.Subscription]
					if !ok {
						send(socketCommand{
							Command: "error",
							Payload: fmt.Sprintf("Failed to unsubscribe id: %d", cmd.Subscription),
						})
					} else {
						sub.Cancel()
					}
				}

				if cmd.Command == "subscribe" {

					sid := id
					id++

					s, err := mqtt.Subscribe(ninja.GetSubscribeTopic(cmd.Payload), func(topic string, payload []byte) {

						out := socketCommand{
							Command:      "message",
							Subscription: sid,
							Payload:      string(payload),
							Topic:        topic,
						}

						if params, ok := ninja.MatchTopicPattern(cmd.Payload, topic); ok {
							out.Params = *params
						}

						send(out)
					})

					if err != nil {
						send(socketCommand{
							Command: "error",
							Payload: fmt.Sprintf("Failed to subscribe to %s: %s", cmd.Payload, err),
						})
					} else {

						subscriptions[sid] = s

						send(socketCommand{
							Command:      "suback",
							Subscription: sid,
						})
					}
				}

				if cmd.Command == "publish" {
					mqtt.Publish(cmd.Topic, []byte(cmd.Payload))
				}

			}
		}()

	})

	listenAddress := fmt.Sprintf(":%d", config.MustInt("homecloud.websocket.port"))

	s.log.Infof("Listening at %s", listenAddress)

	return http.ListenAndServe(listenAddress, nil)
}
<commit_msg>serialize the use of the response socket.<commit_after>package homecloud

import (
	"encoding/json"
	"fmt"
	"net/http"

	"github.com/gorilla/websocket"
	"github.com/ninjasphere/go-ninja/api"
	"github.com/ninjasphere/go-ninja/bus"
	"github.com/ninjasphere/go-ninja/config"
	"github.com/ninjasphere/go-ninja/logger"
)

var upgrader = websocket.Upgrader{
	ReadBufferSize:  1024,
	WriteBufferSize: 1024,
	CheckOrigin:     func(r *http.Request) bool { return true },
}

type socketCommand struct {
	Command      string            `json:"command"`
	Topic        string            `json:"topic"`
	Payload      string            `json:"payload"`
	Subscription int               `json:"subscription"`
	Params       map[string]string `json:"params"`
}

type WebsocketServer struct {
	log *logger.Logger
}

func (s *WebsocketServer) PostConstruct() error {
	s.log = logger.GetLogger("WebsocketServer")
	return s.Listen()
}

func (s *WebsocketServer) Listen() error {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {

		log.Debugf("Websocket incoming connection")

		ws, err := upgrader.Upgrade(w, r, nil)
		if err != nil {
			log.Errorf("Websocket upgrade error: %s", err)
			return
		}

		clientID := "websocket-" + r.RemoteAddr
		mqttURL := fmt.Sprintf("%s:%d", config.MustString("mqtt", "host"), config.MustInt("mqtt", "port"))

		log.Infof("Connecting to %s using cid:%s", mqttURL, clientID)

		mqtt := bus.MustConnect(mqttURL, clientID)

		subscriptions := make(map[int]*bus.Subscription)

		queue := make(chan *socketCommand)

		func() {
			for {
				command := <-queue
				if command != nil {
					js, _ := json.Marshal(*command)
					if err = ws.WriteMessage(websocket.TextMessage, js); err != nil {
						log.Errorf("Websocket failed writing message error: %s", err)
					}
				} else {
					break
				}
			}
		}()

		send := func(command socketCommand) {
			queue <- &command
		}

		id := 0

		go func() {
			for {
				_, p, err := ws.ReadMessage()
				if err != nil {
					close(queue)
					mqtt.Destroy()
					return
				}

				var cmd socketCommand
				err = json.Unmarshal(p, &cmd)

				log.Debugf("Incoming ws message: %s", p)

				if cmd.Command == "unsubscribe" {
					sub, ok := subscriptions[cmd.Subscription]
					if !ok {
						send(socketCommand{
							Command: "error",
							Payload: fmt.Sprintf("Failed to unsubscribe id: %d", cmd.Subscription),
						})
					} else {
						sub.Cancel()
					}
				}

				if cmd.Command == "subscribe" {

					sid := id
					id++

					s, err := mqtt.Subscribe(ninja.GetSubscribeTopic(cmd.Payload), func(topic string, payload []byte) {

						out := socketCommand{
							Command:      "message",
							Subscription: sid,
							Payload:      string(payload),
							Topic:        topic,
						}

						if params, ok := ninja.MatchTopicPattern(cmd.Payload, topic); ok {
							out.Params = *params
						}

						send(out)
					})

					if err != nil {
						send(socketCommand{
							Command: "error",
							Payload: fmt.Sprintf("Failed to subscribe to %s: %s", cmd.Payload, err),
						})
					} else {

						subscriptions[sid] = s

						send(socketCommand{
							Command:      "suback",
							Subscription: sid,
						})
					}
				}

				if cmd.Command == "publish" {
					mqtt.Publish(cmd.Topic, []byte(cmd.Payload))
				}

			}
		}()

	})

	listenAddress := fmt.Sprintf(":%d", config.MustInt("homecloud.websocket.port"))

	s.log.Infof("Listening at %s", listenAddress)

	return http.ListenAndServe(listenAddress, nil)
}
<|endoftext|>


<commit_before>package common

// IsValidRegion returns true if the supplied region is a valid AWS
// region and false if it's not.
func ValidateRegion(region string) bool {
	var regions = [11]string{"us-east-1", "us-west-2", "us-west-1", "eu-west-1",
		"eu-central-1", "ap-southeast-1", "ap-southeast-2", "ap-northeast-1",
		"sa-east-1", "cn-north-1", "us-gov-west-1"}

	for _, valid := range regions {
		if region == valid {
			return true
		}
	}
	return false
}
<commit_msg>sort regions by name<commit_after>package common

// IsValidRegion returns true if the supplied region is a valid AWS
// region and false if it's not.
func ValidateRegion(region string) bool {
	var regions = [11]string{"ap-northeast-1", "ap-southeast-1", "ap-southeast-2",
		"cn-north-1", "eu-central-1", "eu-west-1", "sa-east-1",
		"us-east-1", "us-gov-west-1", "us-west-1", "us-west-2"}

	for _, valid := range regions {
		if region == valid {
			return true
		}
	}
	return false
}
<|endoftext|>


<commit_before>package admin

import (
	"log"
	"net/http"
	"path"
	"regexp"
	"strings"
	"time"

	"github.com/qor/qor"
	"github.com/qor/qor/roles"
)

// Middleware is a way to filter a request and response coming into your application
// Register new middlewares with `admin.GetRouter().Use(func(*Context, *Middleware))`
// It will be called in order, it need to be registered before `admin.MountTo`
type Middleware struct {
	Handler func(*Context, *Middleware)
	next    *Middleware
}

// Next will call the next middleware
func (middleware Middleware) Next(context *Context) {
	if next := middleware.next; next != nil {
		next.Handler(context, next)
	}
}

// Router contains registered routers
type Router struct {
	Prefix      string
	routers     map[string][]routeHandler
	middlewares []*Middleware
}

func newRouter() *Router {
	return &Router{routers: map[string][]routeHandler{
		"GET":    []routeHandler{},
		"PUT":    []routeHandler{},
		"POST":   []routeHandler{},
		"DELETE": []routeHandler{},
	}}
}

// Use reigster a middleware to the router
func (r *Router) Use(handler func(*Context, *Middleware)) {
	r.middlewares = append(r.middlewares, &Middleware{Handler: handler})
}

// Get register a GET request handle with the given path
func (r *Router) Get(path string, handle requestHandler) {
	r.routers["GET"] = append(r.routers["GET"], routeHandler{Path: path, Handle: handle})
}

// Post register a POST request handle with the given path
func (r *Router) Post(path string, handle requestHandler) {
	r.routers["POST"] = append(r.routers["POST"], routeHandler{Path: path, Handle: handle})
}

// Put register a PUT request handle with the given path
func (r *Router) Put(path string, handle requestHandler) {
	r.routers["PUT"] = append(r.routers["PUT"], routeHandler{Path: path, Handle: handle})
}

// Delete register a DELETE request handle with the given path
func (r *Router) Delete(path string, handle requestHandler) {
	r.routers["DELETE"] = append(r.routers["DELETE"], routeHandler{Path: path, Handle: handle})
}

// MountTo mount the service into mux (HTTP request multiplexer) with given path
func (admin *Admin) MountTo(mountTo string, mux *http.ServeMux) {
	prefix := "/" + strings.Trim(mountTo, "/")
	router := admin.router
	router.Prefix = prefix

	admin.compile()

	controller := &controller{admin}
	router.Get("", controller.Dashboard)
	router.Get("/!search", controller.SearchCenter)

	var registerResourceToRouter func(*Resource, ...string)
	registerResourceToRouter = func(res *Resource, modes ...string) {
		var prefix = func(r *Resource) string {
			p := r.ToParam()
			for r.base != nil {
				p = path.Join(r.base.ToParam(), ":id", p)
				r = r.base
			}
			return "/" + strings.Trim(p, "/")
		}(res)

		for _, mode := range modes {
			if mode == "create" {
				// New
				router.Get(path.Join(prefix, "new"), controller.New)

				// Create
				router.Post(prefix, controller.Create)
			}

			if mode == "read" {
				// Index
				router.Get(prefix, controller.Index)

				// Show
				router.Get(path.Join(prefix, ":id"), controller.Show)
			}

			if mode == "update" {
				// Edit
				router.Get(path.Join(prefix, ":id", "edit"), controller.Edit)

				// Update
				router.Put(path.Join(prefix, ":id"), controller.Update)
				router.Post(path.Join(prefix, ":id"), controller.Update)

				// Action
				for _, action := range res.actions {
					router.Post(path.Join(prefix, ":id", action.Name), controller.Action)
				}
			}

			if mode == "delete" {
				// Delete
				router.Delete(path.Join(prefix, ":id"), controller.Delete)
			}
		}

		// Sub Resources
		for _, meta := range res.ConvertSectionToMetas(res.NewAttrs()) {
			if meta.FieldStruct != nil && meta.FieldStruct.Relationship != nil {
				registerResourceToRouter(meta.Resource, "create")
			}
		}

		for _, meta := range res.ConvertSectionToMetas(res.ShowAttrs()) {
			if meta.FieldStruct != nil && meta.FieldStruct.Relationship != nil {
				registerResourceToRouter(meta.Resource, "read")
			}
		}

		for _, meta := range res.ConvertSectionToMetas(res.EditAttrs()) {
			if meta.FieldStruct != nil && meta.FieldStruct.Relationship != nil {
				registerResourceToRouter(meta.Resource, "update", "delete")
			}
		}
	}

	for _, res := range admin.resources {
		if !res.Config.Invisible {
			registerResourceToRouter(res, "create", "read", "update", "delete")
		}
	}

	mux.Handle(prefix, admin)     // /:prefix
	mux.Handle(prefix+"/", admin) // /:prefix/:xxx
}

func (admin *Admin) compile() {
	admin.generateMenuLinks()

	for _, res := range admin.resources {
		res.configure()
	}

	router := admin.GetRouter()
	router.Use(func(context *Context, middleware *Middleware) {
		writer := context.Writer
		request := context.Request

		// 128 MB
		request.ParseMultipartForm(32 << 22)
		if len(request.Form["_method"]) > 0 {
			request.Method = strings.ToUpper(request.Form["_method"][0])
		}

		var pathMatch = regexp.MustCompile(path.Join(router.Prefix, `(\w+)(?:/(\w+))?[^/]*`))
		var matches = pathMatch.FindStringSubmatch(request.URL.Path)
		if len(matches) > 1 {
			context.setResource(admin.GetResource(matches[1]))
			if len(matches) > 2 {
				context.ResourceID = matches[2]
			}
		}

		handlers := router.routers[strings.ToUpper(request.Method)]
		relativePath := strings.TrimPrefix(request.URL.Path, router.Prefix)
		for _, handler := range handlers {
			if handler.Path == relativePath {
				handler.Handle(context)
				return
			}
		}

		http.NotFound(writer, request)
	})

	for index, middleware := range router.middlewares {
		if len(router.middlewares) > index+1 {
			middleware.next = router.middlewares[index+1]
		}
	}
}

// ServeHTTP dispatches the handler registered in the matched route
func (admin *Admin) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	var relativePath = strings.TrimPrefix(req.URL.Path, admin.router.Prefix)
	var context = admin.NewContext(w, req)

	if regexp.MustCompile("^/assets/.*$").MatchString(relativePath) {
		(&controller{admin}).Asset(context)
		return
	}

	defer func() func() {
		begin := time.Now()
		log.Printf("Start [%s] %s\n", req.Method, req.RequestURI)

		return func() {
			log.Printf("Finish [%s] %s Took %.2fms\n", req.Method, req.RequestURI, time.Now().Sub(begin).Seconds()*1000)
		}
	}()()

	var currentUser qor.CurrentUser
	if admin.auth != nil {
		if currentUser = admin.auth.GetCurrentUser(context); currentUser == nil {
			http.Redirect(w, req, admin.auth.LoginURL(context), http.StatusSeeOther)
			return
		} else {
			context.CurrentUser = currentUser
			context.SetDB(context.GetDB().Set("qor:current_user", context.CurrentUser))
		}
	}
	context.Roles = roles.MatchedRoles(req, currentUser)

	// Call first middleware
	for _, middleware := range admin.router.middlewares {
		middleware.Handler(context, middleware)
		break
	}
}
<commit_msg>Update matcher<commit_after>package admin

import (
	"log"
	"net/http"
	"path"
	"regexp"
	"strings"
	"time"

	"github.com/qor/qor"
	"github.com/qor/qor/roles"
)

// Middleware is a way to filter a request and response coming into your application
// Register new middlewares with `admin.GetRouter().Use(func(*Context, *Middleware))`
// It will be called in order, it need to be registered before `admin.MountTo`
type Middleware struct {
	Handler func(*Context, *Middleware)
	next    *Middleware
}

// Next will call the next middleware
func (middleware Middleware) Next(context *Context) {
	if next := middleware.next; next != nil {
		next.Handler(context, next)
	}
}

// Router contains registered routers
type Router struct {
	Prefix      string
	routers     map[string][]routeHandler
	middlewares []*Middleware
}

func newRouter() *Router {
	return &Router{routers: map[string][]routeHandler{
		"GET":    []routeHandler{},
		"PUT":    []routeHandler{},
		"POST":   []routeHandler{},
		"DELETE": []routeHandler{},
	}}
}

// Use reigster a middleware to the router
func (r *Router) Use(handler func(*Context, *Middleware)) {
	r.middlewares = append(r.middlewares, &Middleware{Handler: handler})
}

// Get register a GET request handle with the given path
func (r *Router) Get(path string, handle requestHandler) {
	r.routers["GET"] = append(r.routers["GET"], routeHandler{Path: path, Handle: handle})
}

// Post register a POST request handle with the given path
func (r *Router) Post(path string, handle requestHandler) {
	r.routers["POST"] = append(r.routers["POST"], routeHandler{Path: path, Handle: handle})
}

// Put register a PUT request handle with the given path
func (r *Router) Put(path string, handle requestHandler) {
	r.routers["PUT"] = append(r.routers["PUT"], routeHandler{Path: path, Handle: handle})
}

// Delete register a DELETE request handle with the given path
func (r *Router) Delete(path string, handle requestHandler) {
	r.routers["DELETE"] = append(r.routers["DELETE"], routeHandler{Path: path, Handle: handle})
}

// MountTo mount the service into mux (HTTP request multiplexer) with given path
func (admin *Admin) MountTo(mountTo string, mux *http.ServeMux) {
	prefix := "/" + strings.Trim(mountTo, "/")
	router := admin.router
	router.Prefix = prefix

	admin.compile()

	controller := &controller{admin}
	router.Get("", controller.Dashboard)
	router.Get("/!search", controller.SearchCenter)

	var registerResourceToRouter func(*Resource, ...string)
	registerResourceToRouter = func(res *Resource, modes ...string) {
		var prefix = func(r *Resource) string {
			p := r.ToParam()
			for r.base != nil {
				p = path.Join(r.base.ToParam(), ":id", p)
				r = r.base
			}
			return "/" + strings.Trim(p, "/")
		}(res)

		for _, mode := range modes {
			if mode == "create" {
				// New
				router.Get(path.Join(prefix, "new"), controller.New)

				// Create
				router.Post(prefix, controller.Create)
			}

			if mode == "read" {
				// Index
				router.Get(prefix, controller.Index)

				// Show
				router.Get(path.Join(prefix, ":id"), controller.Show)
			}

			if mode == "update" {
				// Edit
				router.Get(path.Join(prefix, ":id", "edit"), controller.Edit)

				// Update
				router.Put(path.Join(prefix, ":id"), controller.Update)
				router.Post(path.Join(prefix, ":id"), controller.Update)

				// Action
				for _, action := range res.actions {
					router.Post(path.Join(prefix, ":id", action.Name), controller.Action)
				}
			}

			if mode == "delete" {
				// Delete
				router.Delete(path.Join(prefix, ":id"), controller.Delete)
			}
		}

		// Sub Resources
		for _, meta := range res.ConvertSectionToMetas(res.NewAttrs()) {
			if meta.FieldStruct != nil && meta.FieldStruct.Relationship != nil {
				registerResourceToRouter(meta.Resource, "create")
			}
		}

		for _, meta := range res.ConvertSectionToMetas(res.ShowAttrs()) {
			if meta.FieldStruct != nil && meta.FieldStruct.Relationship != nil {
				registerResourceToRouter(meta.Resource, "read")
			}
		}

		for _, meta := range res.ConvertSectionToMetas(res.EditAttrs()) {
			if meta.FieldStruct != nil && meta.FieldStruct.Relationship != nil {
				registerResourceToRouter(meta.Resource, "update", "delete")
			}
		}
	}

	for _, res := range admin.resources {
		if !res.Config.Invisible {
			registerResourceToRouter(res, "create", "read", "update", "delete")
		}
	}

	mux.Handle(prefix, admin)     // /:prefix
	mux.Handle(prefix+"/", admin) // /:prefix/:xxx
}

func (admin *Admin) compile() {
	admin.generateMenuLinks()

	for _, res := range admin.resources {
		res.configure()
	}

	router := admin.GetRouter()
	router.Use(func(context *Context, middleware *Middleware) {
		writer := context.Writer
		request := context.Request

		// 128 MB
		request.ParseMultipartForm(32 << 22)
		if len(request.Form["_method"]) > 0 {
			request.Method = strings.ToUpper(request.Form["_method"][0])
		}

		var pathMatch = regexp.MustCompile(path.Join(router.Prefix, `(\w+)(?:/(\w+))?[^/]*`))
		var matches = pathMatch.FindStringSubmatch(request.URL.Path)
		if len(matches) > 1 {
			context.setResource(admin.GetResource(matches[1]))
			if len(matches) > 2 {
				context.ResourceID = matches[2]
			}
		}

		handlers := router.routers[strings.ToUpper(request.Method)]
		relativePath := strings.TrimPrefix(request.URL.Path, router.Prefix)
		for _, handler := range handlers {
			if params, ok := handler.try(relativePath); ok {
				for key, values := range params {
					for _, value := range values {
						context.Request.URL.Query().Add(key, value)
					}
				}
				handler.Handle(context)
				return
			}
		}

		http.NotFound(writer, request)
	})

	for index, middleware := range router.middlewares {
		if len(router.middlewares) > index+1 {
			middleware.next = router.middlewares[index+1]
		}
	}
}

// ServeHTTP dispatches the handler registered in the matched route
func (admin *Admin) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	var relativePath = strings.TrimPrefix(req.URL.Path, admin.router.Prefix)
	var context = admin.NewContext(w, req)

	if regexp.MustCompile("^/assets/.*$").MatchString(relativePath) {
		(&controller{admin}).Asset(context)
		return
	}

	defer func() func() {
		begin := time.Now()
		log.Printf("Start [%s] %s\n", req.Method, req.RequestURI)

		return func() {
			log.Printf("Finish [%s] %s Took %.2fms\n", req.Method, req.RequestURI, time.Now().Sub(begin).Seconds()*1000)
		}
	}()()

	var currentUser qor.CurrentUser
	if admin.auth != nil {
		if currentUser = admin.auth.GetCurrentUser(context); currentUser == nil {
			http.Redirect(w, req, admin.auth.LoginURL(context), http.StatusSeeOther)
			return
		} else {
			context.CurrentUser = currentUser
			context.SetDB(context.GetDB().Set("qor:current_user", context.CurrentUser))
		}
	}
	context.Roles = roles.MatchedRoles(req, currentUser)

	// Call first middleware
	for _, middleware := range admin.router.middlewares {
		middleware.Handler(context, middleware)
		break
	}
}
<|endoftext|>


<commit_before>// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package agent provides hooks programs can register to retrieve
// diagnostics data by using gops.
package agent

import (
	"fmt"
	"net"
	"os"
	gosignal "os/signal"
	"runtime"
	"runtime/pprof"

	"github.com/google/gops/signal"
)

// Start stars the gops agent on a host process. Once agent started,
// users can use the advanced gops features.
//
// Note: The agent exposes an endpoint via a UNIX socket that can be used by
// any program on the system. Review your security requirements before
// starting the agent.
func Start() error {
	// TODO(jbd): Expose these endpoints on HTTP. Then, we can enable
	// the agent on Windows systems.
	sock := fmt.Sprintf("/tmp/gops%d.sock", os.Getpid())
	l, err := net.Listen("unix", sock)
	if err != nil {
		return err
	}
	fmt.Println(sock)

	c := make(chan os.Signal, 1)
	gosignal.Notify(c, os.Interrupt)
	go func() {
		// cleanup the socket on shutdown.
		<-c
		os.Remove(sock)
		os.Exit(1)
	}()

	go func() {
		buf := make([]byte, 1)
		for {
			fd, err := l.Accept()
			if err != nil {
				fmt.Fprintf(os.Stderr, "gops: %v", err)
				continue
			}
			if _, err := fd.Read(buf); err != nil {
				fmt.Fprintf(os.Stderr, "gops: %v", err)
				continue
			}
			if err := handle(fd, buf); err != nil {
				fmt.Fprintf(os.Stderr, "gops: %v", err)
				continue
			}
			fd.Close()
		}
	}()
	return err
}

func handle(conn net.Conn, msg []byte) error {
	switch msg[0] {
	case signal.StackTrace:
		buf := make([]byte, 1<<16)
		n := runtime.Stack(buf, true)
		_, err := conn.Write(buf[:n])
		return err
	case signal.GC:
		runtime.GC()
		_, err := conn.Write([]byte("ok"))
		return err
	case signal.MemStats:
		var s runtime.MemStats
		runtime.ReadMemStats(&s)
		fmt.Fprintf(conn, "alloc: %v bytes\n", s.Alloc)
		fmt.Fprintf(conn, "total-alloc: %v bytes\n", s.TotalAlloc)
		fmt.Fprintf(conn, "sys: %v bytes\n", s.Sys)
		fmt.Fprintf(conn, "lookups: %v\n", s.Lookups)
		fmt.Fprintf(conn, "mallocs: %v\n", s.Mallocs)
		fmt.Fprintf(conn, "frees: %v\n", s.Frees)
		fmt.Fprintf(conn, "heap-alloc: %v bytes\n", s.HeapAlloc)
		fmt.Fprintf(conn, "heap-sys: %v bytes\n", s.HeapSys)
		fmt.Fprintf(conn, "heap-idle: %v bytes\n", s.HeapIdle)
		fmt.Fprintf(conn, "heap-in-use: %v bytes\n", s.HeapInuse)
		fmt.Fprintf(conn, "heap-released: %v bytes\n", s.HeapReleased)
		fmt.Fprintf(conn, "heap-objects: %v\n", s.HeapObjects)
		fmt.Fprintf(conn, "stack-in-use: %v bytes\n", s.StackInuse)
		fmt.Fprintf(conn, "stack-sys: %v bytes\n", s.StackSys)
		fmt.Fprintf(conn, "next-gc: when heap-alloc >= %v bytes\n", s.NextGC)
		fmt.Fprintf(conn, "last-gc: %v ns ago\n", s.LastGC)
		fmt.Fprintf(conn, "gc-pause: %v ns\n", s.PauseTotalNs)
		fmt.Fprintf(conn, "num-gc: %v\n", s.NumGC)
		fmt.Fprintf(conn, "enable-gc: %v\n", s.EnableGC)
		fmt.Fprintf(conn, "debug-gc: %v\n", s.DebugGC)
	case signal.Version:
		fmt.Fprintf(conn, "%v\n", runtime.Version())
	case signal.HeapProfile:
		pprof.Lookup("heap").WriteTo(conn, 1)
	case signal.CPUProfile:
		panic("not implemented")
	}
	return nil
}
<commit_msg>remove Println<commit_after>// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package agent provides hooks programs can register to retrieve
// diagnostics data by using gops.
package agent

import (
	"fmt"
	"net"
	"os"
	gosignal "os/signal"
	"runtime"
	"runtime/pprof"

	"github.com/google/gops/signal"
)

// Start stars the gops agent on a host process. Once agent started,
// users can use the advanced gops features.
//
// Note: The agent exposes an endpoint via a UNIX socket that can be used by
// any program on the system. Review your security requirements before
// starting the agent.
func Start() error {
	// TODO(jbd): Expose these endpoints on HTTP. Then, we can enable
	// the agent on Windows systems.
	sock := fmt.Sprintf("/tmp/gops%d.sock", os.Getpid())
	l, err := net.Listen("unix", sock)
	if err != nil {
		return err
	}

	c := make(chan os.Signal, 1)
	gosignal.Notify(c, os.Interrupt)
	go func() {
		// cleanup the socket on shutdown.
		<-c
		os.Remove(sock)
		os.Exit(1)
	}()

	go func() {
		buf := make([]byte, 1)
		for {
			fd, err := l.Accept()
			if err != nil {
				fmt.Fprintf(os.Stderr, "gops: %v", err)
				continue
			}
			if _, err := fd.Read(buf); err != nil {
				fmt.Fprintf(os.Stderr, "gops: %v", err)
				continue
			}
			if err := handle(fd, buf); err != nil {
				fmt.Fprintf(os.Stderr, "gops: %v", err)
				continue
			}
			fd.Close()
		}
	}()
	return err
}

func handle(conn net.Conn, msg []byte) error {
	switch msg[0] {
	case signal.StackTrace:
		buf := make([]byte, 1<<16)
		n := runtime.Stack(buf, true)
		_, err := conn.Write(buf[:n])
		return err
	case signal.GC:
		runtime.GC()
		_, err := conn.Write([]byte("ok"))
		return err
	case signal.MemStats:
		var s runtime.MemStats
		runtime.ReadMemStats(&s)
		fmt.Fprintf(conn, "alloc: %v bytes\n", s.Alloc)
		fmt.Fprintf(conn, "total-alloc: %v bytes\n", s.TotalAlloc)
		fmt.Fprintf(conn, "sys: %v bytes\n", s.Sys)
		fmt.Fprintf(conn, "lookups: %v\n", s.Lookups)
		fmt.Fprintf(conn, "mallocs: %v\n", s.Mallocs)
		fmt.Fprintf(conn, "frees: %v\n", s.Frees)
		fmt.Fprintf(conn, "heap-alloc: %v bytes\n", s.HeapAlloc)
		fmt.Fprintf(conn, "heap-sys: %v bytes\n", s.HeapSys)
		fmt.Fprintf(conn, "heap-idle: %v bytes\n", s.HeapIdle)
		fmt.Fprintf(conn, "heap-in-use: %v bytes\n", s.HeapInuse)
		fmt.Fprintf(conn, "heap-released: %v bytes\n", s.HeapReleased)
		fmt.Fprintf(conn, "heap-objects: %v\n", s.HeapObjects)
		fmt.Fprintf(conn, "stack-in-use: %v bytes\n", s.StackInuse)
		fmt.Fprintf(conn, "stack-sys: %v bytes\n", s.StackSys)
		fmt.Fprintf(conn, "next-gc: when heap-alloc >= %v bytes\n", s.NextGC)
		fmt.Fprintf(conn, "last-gc: %v ns ago\n", s.LastGC)
		fmt.Fprintf(conn, "gc-pause: %v ns\n", s.PauseTotalNs)
		fmt.Fprintf(conn, "num-gc: %v\n", s.NumGC)
		fmt.Fprintf(conn, "enable-gc: %v\n", s.EnableGC)
		fmt.Fprintf(conn, "debug-gc: %v\n", s.DebugGC)
	case signal.Version:
		fmt.Fprintf(conn, "%v\n", runtime.Version())
	case signal.HeapProfile:
		pprof.Lookup("heap").WriteTo(conn, 1)
	case signal.CPUProfile:
		panic("not implemented")
	}
	return nil
}
<|endoftext|>