<commit_before>// Copyright (c) 2014 Couchbase, Inc.
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
// except in compliance with the License. You may obtain a copy of the License at
//   http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed under the
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.

package indexer

import (
	"bytes"
	"errors"
	"github.com/couchbase/cbauth/metakv"
	"github.com/couchbase/indexing/secondary/common"
	"github.com/couchbase/indexing/secondary/logging"
	"github.com/couchbase/indexing/secondary/pipeline"
	"io/ioutil"
	"net/http"
	"time"
)

const (
	indexCompactonMetaPath = common.IndexingMetaDir + "triggerCompaction"
)

// Implements dynamic settings management for indexer
type settingsManager struct {
	supvCmdch       MsgChannel
	supvMsgch       MsgChannel
	config          common.Config
	cancelCh        chan struct{}
	compactionToken []byte
}

func NewSettingsManager(supvCmdch MsgChannel,
	supvMsgch MsgChannel, config common.Config) (settingsManager, common.Config, Message) {
	s := settingsManager{
		supvCmdch: supvCmdch,
		supvMsgch: supvMsgch,
		config:    config,
		cancelCh:  make(chan struct{}),
	}

	config, err := common.GetSettingsConfig(config)
	if err != nil {
		return s, nil, &MsgError{
			err: Error{
				category: INDEXER,
				cause:    err,
				severity: FATAL,
			}}
	}

	ncpu := common.SetNumCPUs(config["indexer.settings.max_cpu_percent"].Int())
	logging.Infof("Setting maxcpus = %d", ncpu)

	setBlockPoolSize(nil, config)
	setLogger(config)

	http.HandleFunc("/settings", s.handleSettingsReq)
	http.HandleFunc("/triggerCompaction", s.handleCompactionTrigger)
	go func() {
		for {
			err := metakv.RunObserveChildren("/", s.metaKVCallback, s.cancelCh)
			if err == nil {
				return
			} else {
				logging.Errorf("IndexerSettingsManager: metakv notifier failed (%v)..Restarting", err)
			}
		}
	}()

	indexerConfig := config.SectionConfig("indexer.", true)
	return s, indexerConfig, &MsgSuccess{}
}

func (s *settingsManager) writeOk(w http.ResponseWriter) {
	w.WriteHeader(http.StatusOK)
	w.Write([]byte("OK\n"))
}

func (s *settingsManager) writeError(w http.ResponseWriter, err error) {
	w.WriteHeader(http.StatusBadRequest)
	w.Write([]byte(err.Error() + "\n"))
}

func (s *settingsManager) writeJson(w http.ResponseWriter, json []byte) {
	header := w.Header()
	header["Content-Type"] = []string{"application/json"}
	w.WriteHeader(200)
	w.Write(json)
	w.Write([]byte("\n"))
}

func (s *settingsManager) validateAuth(w http.ResponseWriter, r *http.Request) bool {
	valid, err := common.IsAuthValid(r, s.config["indexer.clusterAddr"].String())
	if err != nil {
		s.writeError(w, err)
	} else if valid == false {
		w.WriteHeader(401)
		w.Write([]byte("401 Unauthorized\n"))
	}
	return valid
}

func (s *settingsManager) handleSettingsReq(w http.ResponseWriter, r *http.Request) {
	if !s.validateAuth(w, r) {
		return
	}

	if r.Method == "POST" {
		bytes, _ := ioutil.ReadAll(r.Body)

		config := s.config.Clone()
		current, rev, err := metakv.Get(common.IndexingSettingsMetaPath)
		if err == nil {
			if len(current) > 0 {
				config.Update(current)
			}
			err = config.Update(bytes)
		}

		if err != nil {
			s.writeError(w, err)
			return
		}

		settingsConfig := config.FilterConfig(".settings.")
		newSettingsBytes := settingsConfig.Json()
		if err = metakv.Set(common.IndexingSettingsMetaPath, newSettingsBytes, rev); err != nil {
			s.writeError(w, err)
			return
		}
		s.writeOk(w)
	} else if r.Method == "GET" {
		settingsConfig, err := common.GetSettingsConfig(s.config)
		if err != nil {
			s.writeError(w, err)
			return
		}
		s.writeJson(w, settingsConfig.FilterConfig(".settings.").Json())
	} else {
		s.writeError(w, errors.New("Unsupported method"))
		return
	}
}

func (s *settingsManager) handleCompactionTrigger(w http.ResponseWriter, r *http.Request) {
	if !s.validateAuth(w, r) {
		return
	}
	_, rev, err := metakv.Get(indexCompactonMetaPath)
	if err != nil {
		s.writeError(w, err)
		return
	}

	newToken := time.Now().String()
	if err = metakv.Set(indexCompactonMetaPath, []byte(newToken), rev); err != nil {
		s.writeError(w, err)
		return
	}

	s.writeOk(w)
}

func (s *settingsManager) run() {
loop:
	for {
		select {
		case cmd, ok := <-s.supvCmdch:
			if ok {
				if cmd.GetMsgType() == STORAGE_MGR_SHUTDOWN {
					logging.Infof("SettingsManager::run Shutting Down")
					close(s.cancelCh)
					s.supvCmdch <- &MsgSuccess{}
					break loop
				}
			} else {
				break loop
			}
		}
	}
}

func (s *settingsManager) metaKVCallback(path string, value []byte, rev interface{}) error {
	if path == common.IndexingSettingsMetaPath {
		logging.Infof("New settings received: \n%s", string(value))
		config := s.config.Clone()
		config.Update(value)
		setBlockPoolSize(s.config, config)
		s.config = config

		ncpu := common.SetNumCPUs(config["indexer.settings.max_cpu_percent"].Int())
		logging.Infof("Setting maxcpus = %d", ncpu)

		setLogger(config)

		indexerConfig := s.config.SectionConfig("indexer.", true)
		s.supvMsgch <- &MsgConfigUpdate{
			cfg: indexerConfig,
		}
	} else if path == indexCompactonMetaPath {
		currentToken := s.compactionToken
		s.compactionToken = value
		if bytes.Equal(currentToken, value) {
			return nil
		}

		logging.Infof("Manual compaction trigger requested")
		replych := make(chan []IndexStorageStats)
		statReq := &MsgIndexStorageStats{respch: replych}
		s.supvMsgch <- statReq
		stats := <-replych
		// XXX: minFile size check can be applied
		go func() {
			for _, is := range stats {
				errch := make(chan error)
				compactReq := &MsgIndexCompact{
					instId: is.InstId,
					errch:  errch,
				}
				logging.Infof("ManualCompaction: Compacting index instance:%v", is.InstId)
				s.supvMsgch <- compactReq
				err := <-errch
				if err == nil {
					logging.Infof("ManualCompaction: Finished compacting index instance:%v", is.InstId)
				} else {
					logging.Errorf("ManualCompaction: Index instance:%v Compaction failed with reason - %v", is.InstId, err)
				}
			}
		}()
	}

	return nil
}

func setLogger(config common.Config) {
	logLevel := config["indexer.settings.log_level"].String()
	level := logging.Level(logLevel)
	logging.Infof("Setting log level to %v", level)
	logging.SetLogLevel(level)
}

func setBlockPoolSize(o, n common.Config) {
	var oldSz, newSz int
	if o != nil {
		oldSz = o["indexer.settings.bufferPoolBlockSize"].Int()
	}

	newSz = n["indexer.settings.bufferPoolBlockSize"].Int()

	if oldSz < newSz {
		pipeline.SetupBlockPool(newSz)
		logging.Infof("Setting buffer block size to %d bytes", newSz)
	} else if oldSz > newSz {
		logging.Errorf("Setting buffer block size from %d to %d failed "+
			" - Only sizes higher than current size is allowed during runtime",
			oldSz, newSz)
	}
}
<commit_msg>MB-15984: expose all settings via indexer-settings-endpoint.<commit_after>// Copyright (c) 2014 Couchbase, Inc.
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
// except in compliance with the License. You may obtain a copy of the License at
//   http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed under the
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.

package indexer

import (
	"bytes"
	"errors"
	"github.com/couchbase/cbauth/metakv"
	"github.com/couchbase/indexing/secondary/common"
	"github.com/couchbase/indexing/secondary/logging"
	"github.com/couchbase/indexing/secondary/pipeline"
	"io/ioutil"
	"net/http"
	"time"
)

const (
	indexCompactonMetaPath = common.IndexingMetaDir + "triggerCompaction"
)

// Implements dynamic settings management for indexer
type settingsManager struct {
	supvCmdch       MsgChannel
	supvMsgch       MsgChannel
	config          common.Config
	cancelCh        chan struct{}
	compactionToken []byte
}

func NewSettingsManager(supvCmdch MsgChannel,
	supvMsgch MsgChannel, config common.Config) (settingsManager, common.Config, Message) {
	s := settingsManager{
		supvCmdch: supvCmdch,
		supvMsgch: supvMsgch,
		config:    config,
		cancelCh:  make(chan struct{}),
	}

	config, err := common.GetSettingsConfig(config)
	if err != nil {
		return s, nil, &MsgError{
			err: Error{
				category: INDEXER,
				cause:    err,
				severity: FATAL,
			}}
	}

	ncpu := common.SetNumCPUs(config["indexer.settings.max_cpu_percent"].Int())
	logging.Infof("Setting maxcpus = %d", ncpu)

	setBlockPoolSize(nil, config)
	setLogger(config)

	http.HandleFunc("/settings", s.handleSettingsReq)
	http.HandleFunc("/triggerCompaction", s.handleCompactionTrigger)
	go func() {
		for {
			err := metakv.RunObserveChildren("/", s.metaKVCallback, s.cancelCh)
			if err == nil {
				return
			} else {
				logging.Errorf("IndexerSettingsManager: metakv notifier failed (%v)..Restarting", err)
			}
		}
	}()

	indexerConfig := config.SectionConfig("indexer.", true)
	return s, indexerConfig, &MsgSuccess{}
}

func (s *settingsManager) writeOk(w http.ResponseWriter) {
	w.WriteHeader(http.StatusOK)
	w.Write([]byte("OK\n"))
}

func (s *settingsManager) writeError(w http.ResponseWriter, err error) {
	w.WriteHeader(http.StatusBadRequest)
	w.Write([]byte(err.Error() + "\n"))
}

func (s *settingsManager) writeJson(w http.ResponseWriter, json []byte) {
	header := w.Header()
	header["Content-Type"] = []string{"application/json"}
	w.WriteHeader(200)
	w.Write(json)
	w.Write([]byte("\n"))
}

func (s *settingsManager) validateAuth(w http.ResponseWriter, r *http.Request) bool {
	valid, err := common.IsAuthValid(r, s.config["indexer.clusterAddr"].String())
	if err != nil {
		s.writeError(w, err)
	} else if valid == false {
		w.WriteHeader(401)
		w.Write([]byte("401 Unauthorized\n"))
	}
	return valid
}

func (s *settingsManager) handleSettingsReq(w http.ResponseWriter, r *http.Request) {
	if !s.validateAuth(w, r) {
		return
	}

	if r.Method == "POST" {
		bytes, _ := ioutil.ReadAll(r.Body)

		config := s.config.Clone()
		current, rev, err := metakv.Get(common.IndexingSettingsMetaPath)
		if err == nil {
			if len(current) > 0 {
				config.Update(current)
			}
			err = config.Update(bytes)
		}

		if err != nil {
			s.writeError(w, err)
			return
		}

		//settingsConfig := config.FilterConfig(".settings.")
		newSettingsBytes := config.Json()
		if err = metakv.Set(common.IndexingSettingsMetaPath, newSettingsBytes, rev); err != nil {
			s.writeError(w, err)
			return
		}
		s.writeOk(w)
	} else if r.Method == "GET" {
		settingsConfig, err := common.GetSettingsConfig(s.config)
		if err != nil {
			s.writeError(w, err)
			return
		}
		s.writeJson(w, settingsConfig.Json())
		// s.writeJson(w, settingsConfig.FilterConfig(".settings.").Json())
	} else {
		s.writeError(w, errors.New("Unsupported method"))
		return
	}
}

func (s *settingsManager) handleCompactionTrigger(w http.ResponseWriter, r *http.Request) {
	if !s.validateAuth(w, r) {
		return
	}
	_, rev, err := metakv.Get(indexCompactonMetaPath)
	if err != nil {
		s.writeError(w, err)
		return
	}

	newToken := time.Now().String()
	if err = metakv.Set(indexCompactonMetaPath, []byte(newToken), rev); err != nil {
		s.writeError(w, err)
		return
	}

	s.writeOk(w)
}

func (s *settingsManager) run() {
loop:
	for {
		select {
		case cmd, ok := <-s.supvCmdch:
			if ok {
				if cmd.GetMsgType() == STORAGE_MGR_SHUTDOWN {
					logging.Infof("SettingsManager::run Shutting Down")
					close(s.cancelCh)
					s.supvCmdch <- &MsgSuccess{}
					break loop
				}
			} else {
				break loop
			}
		}
	}
}

func (s *settingsManager) metaKVCallback(path string, value []byte, rev interface{}) error {
	if path == common.IndexingSettingsMetaPath {
		logging.Infof("New settings received: \n%s", string(value))
		config := s.config.Clone()
		config.Update(value)
		setBlockPoolSize(s.config, config)
		s.config = config

		ncpu := common.SetNumCPUs(config["indexer.settings.max_cpu_percent"].Int())
		logging.Infof("Setting maxcpus = %d", ncpu)

		setLogger(config)

		indexerConfig := s.config.SectionConfig("indexer.", true)
		s.supvMsgch <- &MsgConfigUpdate{
			cfg: indexerConfig,
		}
	} else if path == indexCompactonMetaPath {
		currentToken := s.compactionToken
		s.compactionToken = value
		if bytes.Equal(currentToken, value) {
			return nil
		}

		logging.Infof("Manual compaction trigger requested")
		replych := make(chan []IndexStorageStats)
		statReq := &MsgIndexStorageStats{respch: replych}
		s.supvMsgch <- statReq
		stats := <-replych
		// XXX: minFile size check can be applied
		go func() {
			for _, is := range stats {
				errch := make(chan error)
				compactReq := &MsgIndexCompact{
					instId: is.InstId,
					errch:  errch,
				}
				logging.Infof("ManualCompaction: Compacting index instance:%v", is.InstId)
				s.supvMsgch <- compactReq
				err := <-errch
				if err == nil {
					logging.Infof("ManualCompaction: Finished compacting index instance:%v", is.InstId)
				} else {
					logging.Errorf("ManualCompaction: Index instance:%v Compaction failed with reason - %v", is.InstId, err)
				}
			}
		}()
	}

	return nil
}

func setLogger(config common.Config) {
	logLevel := config["indexer.settings.log_level"].String()
	level := logging.Level(logLevel)
	logging.Infof("Setting log level to %v", level)
	logging.SetLogLevel(level)
}

func setBlockPoolSize(o, n common.Config) {
	var oldSz, newSz int
	if o != nil {
		oldSz = o["indexer.settings.bufferPoolBlockSize"].Int()
	}

	newSz = n["indexer.settings.bufferPoolBlockSize"].Int()

	if oldSz < newSz {
		pipeline.SetupBlockPool(newSz)
		logging.Infof("Setting buffer block size to %d bytes", newSz)
	} else if oldSz > newSz {
		logging.Errorf("Setting buffer block size from %d to %d failed "+
			" - Only sizes higher than current size is allowed during runtime",
			oldSz, newSz)
	}
}
<|endoftext|>


<commit_before>// Copyright ©2016 The gonum 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 testlapack

import (
	"fmt"
	"math/rand"
	"testing"

	"github.com/gonum/blas"
	"github.com/gonum/floats"
)

type Dsytrder interface {
	Dsytrd(uplo blas.Uplo, n int, a []float64, lda int, d, e, tau, work []float64, lwork int)
	Dsytd2er
}

func DsytrdTest(t *testing.T, impl Dsytrder) {
	rnd := rand.New(rand.NewSource(1))
	for _, uplo := range []blas.Uplo{blas.Upper} {
		for _, test := range []struct {
			n, lda int
		}{
			{10, 0},
			{50, 0},
			{100, 0},
			{150, 0},
			{300, 0},

			{10, 20},
			{50, 70},
			{100, 120},
			{150, 170},
			{300, 320},
		} {
			n := test.n
			lda := test.lda
			if lda == 0 {
				lda = n
			}
			a := make([]float64, n*lda)
			for i := range a {
				a[i] = rnd.NormFloat64()
			}
			d2 := make([]float64, n)
			e2 := make([]float64, n)
			tau2 := make([]float64, n)

			aCopy := make([]float64, len(a))
			copy(aCopy, a)
			impl.Dsytd2(uplo, n, a, lda, d2, e2, tau2)
			aAns := make([]float64, len(a))
			copy(aAns, a)

			copy(a, aCopy)
			d := make([]float64, n)
			e := make([]float64, n)
			tau := make([]float64, n)
			work := make([]float64, 1)
			impl.Dsytrd(uplo, n, a, lda, d, e, tau, work, -1)
			work = make([]float64, int(work[0]))
			impl.Dsytrd(uplo, n, a, lda, d, e, tau, work, len(work))
			errStr := fmt.Sprintf("upper = %v, n = %v", uplo == blas.Upper, n)
			if !floats.EqualApprox(a, aAns, 1e-8) {
				t.Errorf("A mismatch: %s", errStr)
			}
			if !floats.EqualApprox(d, d2, 1e-8) {
				t.Errorf("D mismatch: %s", errStr)
			}
			if !floats.EqualApprox(e, e2, 1e-8) {
				t.Errorf("E mismatch: %s", errStr)
			}
			if !floats.EqualApprox(tau, tau2, 1e-8) {
				t.Errorf("Tau mismatch: %s", errStr)
			}
		}
	}
}
<commit_msg>test: add blas.Lower to DsytrdTest<commit_after>// Copyright ©2016 The gonum 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 testlapack

import (
	"fmt"
	"math/rand"
	"testing"

	"github.com/gonum/blas"
	"github.com/gonum/floats"
)

type Dsytrder interface {
	Dsytrd(uplo blas.Uplo, n int, a []float64, lda int, d, e, tau, work []float64, lwork int)
	Dsytd2er
}

func DsytrdTest(t *testing.T, impl Dsytrder) {
	rnd := rand.New(rand.NewSource(1))
	for _, uplo := range []blas.Uplo{blas.Upper, blas.Lower} {
		for _, test := range []struct {
			n, lda int
		}{
			{10, 0},
			{50, 0},
			{100, 0},
			{150, 0},
			{300, 0},

			{10, 20},
			{50, 70},
			{100, 120},
			{150, 170},
			{300, 320},
		} {
			n := test.n
			lda := test.lda
			if lda == 0 {
				lda = n
			}
			a := make([]float64, n*lda)
			for i := range a {
				a[i] = rnd.NormFloat64()
			}
			d2 := make([]float64, n)
			e2 := make([]float64, n)
			tau2 := make([]float64, n)

			aCopy := make([]float64, len(a))
			copy(aCopy, a)
			impl.Dsytd2(uplo, n, a, lda, d2, e2, tau2)
			aAns := make([]float64, len(a))
			copy(aAns, a)

			copy(a, aCopy)
			d := make([]float64, n)
			e := make([]float64, n)
			tau := make([]float64, n)
			work := make([]float64, 1)
			impl.Dsytrd(uplo, n, a, lda, d, e, tau, work, -1)
			work = make([]float64, int(work[0]))
			impl.Dsytrd(uplo, n, a, lda, d, e, tau, work, len(work))
			errStr := fmt.Sprintf("upper = %v, n = %v", uplo == blas.Upper, n)
			if !floats.EqualApprox(a, aAns, 1e-8) {
				t.Errorf("A mismatch: %s", errStr)
			}
			if !floats.EqualApprox(d, d2, 1e-8) {
				t.Errorf("D mismatch: %s", errStr)
			}
			if !floats.EqualApprox(e, e2, 1e-8) {
				t.Errorf("E mismatch: %s", errStr)
			}
			if !floats.EqualApprox(tau, tau2, 1e-8) {
				t.Errorf("Tau mismatch: %s", errStr)
			}
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"net"
	"time"

	log "github.com/cihub/seelog"
	"github.com/stampzilla/gocast"
	"github.com/stampzilla/gocast/events"
	"github.com/stampzilla/gocast/handlers"
	"github.com/stampzilla/gocast/responses"
)

type Chromecast struct {
	Id    string
	Name_ string `json:"Name"`

	PrimaryApp      string
	PrimaryEndpoint string
	Playing         bool
	//Paused          bool

	IsStandBy     bool
	IsActiveInput bool

	Volume float64
	Muted  bool

	Addr net.IP
	Port int

	publish func()

	mediaHandler           *handlers.Media
	mediaConnectionHandler *handlers.Connection

	appLaunch chan string

	*gocast.Device
}

func NewChromecast(d *gocast.Device) *Chromecast {
	c := &Chromecast{
		Device: d,
	}

	d.OnEvent(c.Event)

	c.mediaHandler = &handlers.Media{}
	c.mediaConnectionHandler = &handlers.Connection{}
	c.appLaunch = make(chan string)

	return c
}

func (c *Chromecast) Play() {
	c.mediaHandler.Play()
}
func (c *Chromecast) Pause() {
	c.mediaHandler.Pause()
}
func (c *Chromecast) Stop() {
	c.mediaHandler.Stop()
}

func (c *Chromecast) PlayUrl(url string, contentType string) {
	err := c.Device.ReceiverHandler.LaunchApp(gocast.AppMedia)
	if err != nil && err != handlers.ErrAppAlreadyLaunched {
		log.Error(err)
		return
	}

	if err != handlers.ErrAppAlreadyLaunched {
		//Wait for new media connection to launched app
		if err := c.waitForAppLaunch(gocast.AppMedia); err != nil {
			log.Error(err)
			return
		}
	}

	if contentType == "" {
		contentType = "audio/mpeg"
	}
	item := responses.MediaItem{
		ContentId:   url,
		StreamType:  "BUFFERED",
		ContentType: contentType,
	}
	err = c.mediaHandler.LoadMedia(item, 0, true, map[string]interface{}{})
	if err != nil {
		log.Error(err)
		return
	}
}

func (c *Chromecast) waitForAppLaunch(app string) error {
	select {
	case launchedApp := <-c.appLaunch:
		if app == launchedApp {
			return nil
		}
		return fmt.Errorf("Wrong app launched. Expected %s got %s", app, launchedApp)
	case <-time.After(time.Second * 20):
		return fmt.Errorf("timeout waiting for app launch after 20 seconds")

	}

}
func (c *Chromecast) appLaunched(app string) {
	select {
	case c.appLaunch <- app:
	default:
	}
}

func (c *Chromecast) Event(event events.Event) {
	switch data := event.(type) {
	case events.Connected:
		log.Info(c.Name(), "- Connected")

		c.Addr = c.Ip()
		c.Port = c.Device.Port()
		c.Id = c.Uuid()
		c.Name_ = c.Name()

		state.Add(c)
	case events.Disconnected:
		log.Warn(c.Name(), "- Disconnected")

		state.Remove(c)
	case events.AppStarted:
		log.Info(c.Name(), "- App started:", data.DisplayName, "(", data.AppID, ")")
		//spew.Dump("Data:", data)

		c.PrimaryApp = data.DisplayName
		c.PrimaryEndpoint = data.TransportId

		//If the app supports media controls lets subscribe to it
		if data.HasNamespace("urn:x-cast:com.google.cast.media") {
			log.Info(c.Name(), "- Subscribe cast.tp.connection:", data.DisplayName, "(", data.AppID, ")")
			c.Subscribe("urn:x-cast:com.google.cast.tp.connection", data.TransportId, c.mediaConnectionHandler)
			log.Info(c.Name(), "- Subscribe cast.media:", data.DisplayName, "(", data.AppID, ")")
			c.Subscribe("urn:x-cast:com.google.cast.media", data.TransportId, c.mediaHandler)
		}
		c.appLaunched(data.AppID)
		log.Info(c.Name(), "- Notifying appLanunched:", data.DisplayName, "(", data.AppID, ")")

	case events.AppStopped:
		log.Info(c.Name(), "- App stopped:", data.DisplayName, "(", data.AppID, ")")
		//spew.Dump("Data:", data)

		//unsubscribe from old channels
		for _, v := range data.Namespaces {
			c.UnsubscribeByUrnAndDestinationId(v.Name, data.TransportId)
		}
		c.PrimaryApp = ""
		c.PrimaryEndpoint = ""
		c.Playing = false

	case events.ReceiverStatus:
		c.IsStandBy = data.Status.IsStandBy
		c.IsActiveInput = data.Status.IsActiveInput
		c.Volume = data.Status.Volume.Level
		c.Muted = data.Status.Volume.Muted
	case events.Media:
		playing := c.Playing
		if data.PlayerState == "PLAYING" {
			c.Playing = true
		} else {
			c.Playing = false
		}

		//Only publish if playing state changed
		if playing != c.Playing {
			c.publish()
		}
		return

	//gocast.MediaEvent:
	default:
		log.Warn("unexpected event %T: %#v\n", data, data)
	}

	c.publish()
}
<commit_msg>added more logging to chromecast in order to solve bug<commit_after>package main

import (
	"fmt"
	"net"
	"time"

	log "github.com/cihub/seelog"
	"github.com/stampzilla/gocast"
	"github.com/stampzilla/gocast/events"
	"github.com/stampzilla/gocast/handlers"
	"github.com/stampzilla/gocast/responses"
)

type Chromecast struct {
	Id    string
	Name_ string `json:"Name"`

	PrimaryApp      string
	PrimaryEndpoint string
	Playing         bool
	//Paused          bool

	IsStandBy     bool
	IsActiveInput bool

	Volume float64
	Muted  bool

	Addr net.IP
	Port int

	publish func()

	mediaHandler           *handlers.Media
	mediaConnectionHandler *handlers.Connection

	appLaunch chan string

	*gocast.Device
}

func NewChromecast(d *gocast.Device) *Chromecast {
	c := &Chromecast{
		Device: d,
	}

	d.OnEvent(c.Event)

	c.mediaHandler = &handlers.Media{}
	c.mediaConnectionHandler = &handlers.Connection{}
	c.appLaunch = make(chan string)

	return c
}

func (c *Chromecast) Play() {
	c.mediaHandler.Play()
}
func (c *Chromecast) Pause() {
	c.mediaHandler.Pause()
}
func (c *Chromecast) Stop() {
	c.mediaHandler.Stop()
}

func (c *Chromecast) PlayUrl(url string, contentType string) {
	err := c.Device.ReceiverHandler.LaunchApp(gocast.AppMedia)
	if err != nil && err != handlers.ErrAppAlreadyLaunched {
		log.Error(err)
		return
	}

	if err != handlers.ErrAppAlreadyLaunched {
		//Wait for new media connection to launched app
		if err := c.waitForAppLaunch(gocast.AppMedia); err != nil {
			log.Error(err)
			return
		}
	}

	if contentType == "" {
		contentType = "audio/mpeg"
	}
	item := responses.MediaItem{
		ContentId:   url,
		StreamType:  "BUFFERED",
		ContentType: contentType,
	}
	err = c.mediaHandler.LoadMedia(item, 0, true, map[string]interface{}{})
	if err != nil {
		log.Error(err)
		return
	}
}

func (c *Chromecast) waitForAppLaunch(app string) error {
	select {
	case launchedApp := <-c.appLaunch:
		if app == launchedApp {
			return nil
		}
		return fmt.Errorf("Wrong app launched. Expected %s got %s", app, launchedApp)
	case <-time.After(time.Second * 20):
		return fmt.Errorf("timeout waiting for app launch after 20 seconds")

	}

}
func (c *Chromecast) appLaunched(app string) {
	select {
	case c.appLaunch <- app:
		log.Info("Notified c.appLaunch")
	default:
		log.Info("No one is waiting for appLaunch event")
	}
}

func (c *Chromecast) Event(event events.Event) {
	switch data := event.(type) {
	case events.Connected:
		log.Info(c.Name(), "- Connected")

		c.Addr = c.Ip()
		c.Port = c.Device.Port()
		c.Id = c.Uuid()
		c.Name_ = c.Name()

		state.Add(c)
	case events.Disconnected:
		log.Warn(c.Name(), "- Disconnected")

		state.Remove(c)
	case events.AppStarted:
		log.Info(c.Name(), "- App started:", data.DisplayName, "(", data.AppID, ")")
		//spew.Dump("Data:", data)

		c.PrimaryApp = data.DisplayName
		c.PrimaryEndpoint = data.TransportId

		//If the app supports media controls lets subscribe to it
		if data.HasNamespace("urn:x-cast:com.google.cast.media") {
			log.Info(c.Name(), "- Subscribe cast.tp.connection:", data.DisplayName, "(", data.AppID, ")")
			c.Subscribe("urn:x-cast:com.google.cast.tp.connection", data.TransportId, c.mediaConnectionHandler)
			log.Info(c.Name(), "- Subscribe cast.media:", data.DisplayName, "(", data.AppID, ")")
			c.Subscribe("urn:x-cast:com.google.cast.media", data.TransportId, c.mediaHandler)
		}
		c.appLaunched(data.AppID)
		log.Info(c.Name(), "- Notifying appLanunched:", data.DisplayName, "(", data.AppID, ")")

	case events.AppStopped:
		log.Info(c.Name(), "- App stopped:", data.DisplayName, "(", data.AppID, ")")
		//spew.Dump("Data:", data)

		//unsubscribe from old channels
		for _, v := range data.Namespaces {
			c.UnsubscribeByUrnAndDestinationId(v.Name, data.TransportId)
		}
		c.PrimaryApp = ""
		c.PrimaryEndpoint = ""
		c.Playing = false

	case events.ReceiverStatus:
		c.IsStandBy = data.Status.IsStandBy
		c.IsActiveInput = data.Status.IsActiveInput
		c.Volume = data.Status.Volume.Level
		c.Muted = data.Status.Volume.Muted
	case events.Media:
		playing := c.Playing
		if data.PlayerState == "PLAYING" {
			c.Playing = true
		} else {
			c.Playing = false
		}

		//Only publish if playing state changed
		if playing != c.Playing {
			c.publish()
		}
		return

	//gocast.MediaEvent:
	default:
		log.Warn("unexpected event %T: %#v\n", data, data)
	}

	c.publish()
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"strconv"
	"time"

	"github.com/brotherlogic/goserver"
	"golang.org/x/net/context"
	"google.golang.org/grpc"

	pbd "github.com/brotherlogic/discovery/proto"
	pb "github.com/brotherlogic/gobuildmaster/proto"
	pbs "github.com/brotherlogic/gobuildslave/proto"
	pbg "github.com/brotherlogic/goserver/proto"
	"github.com/brotherlogic/goserver/utils"
)

const (
	intentWait = time.Second
)

// Server the main server type
type Server struct {
	*goserver.GoServer
	config     *pb.Config
	serving    bool
	lastIntent *time.Time
}

type mainChecker struct {
	prev []string
}

func getIP(servertype, servername string) (string, int) {
	conn, err := grpc.Dial(utils.RegistryIP+":"+strconv.Itoa(utils.RegistryPort), grpc.WithInsecure())
	log.Printf("Error? %v", err)
	defer conn.Close()

	registry := pbd.NewDiscoveryServiceClient(conn)
	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	defer cancel()
	r, err := registry.ListAllServices(ctx, &pbd.Empty{}, grpc.FailFast(false))
	if err != nil {
		return "", -1
	}
	for _, s := range r.Services {
		if s.Name == servertype && s.Identifier == servername {
			return s.Ip, int(s.Port)
		}
	}

	return "", -1
}

func (t *mainChecker) getprev() []string {
	return t.prev
}
func (t *mainChecker) setprev(v []string) {
	t.prev = v
}

func (t *mainChecker) assess(server string) (*pbs.JobList, *pbs.Config) {
	list := &pbs.JobList{}
	conf := &pbs.Config{}

	ip, port := getIP("gobuildslave", server)
	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	defer cancel()
	conn, err := grpc.DialContext(ctx, ip+":"+strconv.Itoa(port), grpc.WithInsecure())
	if err != nil {
		return list, conf
	}
	defer conn.Close()

	slave := pbs.NewGoBuildSlaveClient(conn)
	r, err := slave.List(ctx, &pbs.Empty{}, grpc.FailFast(false))
	if err != nil {
		return list, conf
	}

	r2, err := slave.GetConfig(ctx, &pbs.Empty{}, grpc.FailFast(false))
	if err != nil {
		return list, conf
	}

	return r, r2
}

func (t *mainChecker) master(entry *pbd.RegistryEntry) {
	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	defer cancel()
	conn, _ := grpc.DialContext(ctx, entry.GetIp()+":"+strconv.Itoa(int(entry.GetPort())), grpc.WithInsecure())
	defer conn.Close()

	server := pbg.NewGoserverServiceClient(conn)
	log.Printf("SETTING MASTER: %v", entry)
	_, err := server.Mote(ctx, &pbg.MoteRequest{Master: entry.GetMaster()}, grpc.FailFast(false))
	if err != nil {
		log.Printf("RESPONSE: %v", err)
	}
}

func runJob(job *pbs.JobSpec, server string) {
	log.Printf("Run %v on %v", job.Name, server)
	if server != "" {
		ip, port := getIP("gobuildslave", server)
		ctx, cancel := context.WithTimeout(context.Background(), time.Second)
		defer cancel()
		conn, _ := grpc.DialContext(ctx, ip+":"+strconv.Itoa(port), grpc.WithInsecure())
		defer conn.Close()

		slave := pbs.NewGoBuildSlaveClient(conn)
		job.Server = server
		slave.Run(ctx, job, grpc.FailFast(false))
	}
}

func (t *mainChecker) discover() *pbd.ServiceList {
	ret := &pbd.ServiceList{}

	conn, _ := grpc.Dial(utils.RegistryIP+":"+strconv.Itoa(utils.RegistryPort), grpc.WithInsecure())
	defer conn.Close()

	registry := pbd.NewDiscoveryServiceClient(conn)
	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	defer cancel()
	r, err := registry.ListAllServices(ctx, &pbd.Empty{}, grpc.FailFast(false))
	if err == nil {
		for _, s := range r.Services {
			ret.Services = append(ret.Services, s)
		}
	}

	return ret
}

// DoRegister Registers this server
func (s Server) DoRegister(server *grpc.Server) {
	pb.RegisterGoBuildMasterServer(server, &s)
}

// ReportHealth determines if the server is healthy
func (s Server) ReportHealth() bool {
	return true
}

// Mote promotes/demotes this server
func (s Server) Mote(master bool) error {
	return nil
}

//GetState gets the state of the server
func (s Server) GetState() []*pbg.State {
	return []*pbg.State{&pbg.State{Key: "last_intent", TimeValue: s.lastIntent.Unix()}}
}

//Compare compares current state to desired state
func (s Server) Compare(ctx context.Context, in *pb.Empty) (*pb.CompareResponse, error) {
	resp := &pb.CompareResponse{}
	list, _ := getFleetStatus(&mainChecker{})
	cc := &pb.Config{}
	for _, jlist := range list {
		for _, job := range jlist.GetDetails() {
			cc.Intents = append(cc.Intents, &pb.Intent{Spec: job.GetSpec()})
		}
	}
	resp.Current = cc
	resp.Desired = s.config

	return resp, nil
}

func getConfig(c checker) *pb.Config {
	list, _ := getFleetStatus(c)
	config := &pb.Config{}

	for _, jlist := range list {
		for _, job := range jlist.Details {
			found := false
			for _, ij := range config.Intents {
				if job.Spec.Name == ij.Spec.Name {
					ij.Count++
					found = true
				}
			}

			if !found {
				config.Intents = append(config.Intents, &pb.Intent{Spec: &pbs.JobSpec{Name: job.Spec.Name}, Count: 1})
			}
		}
	}

	return config
}

// MatchIntent tries to match the intent with the state of production
func (s *Server) MatchIntent() {
	checker := &mainChecker{}
	for s.serving {
		s.Log(fmt.Sprintf("MATCHING %v", s.serving))
		time.Sleep(intentWait)
		t := time.Now()
		s.lastIntent = &t

		state := getConfig(checker)
		s.Log(fmt.Sprintf("GOT CONFIG"))
		diff := configDiff(s.config, state)
		s.Log(fmt.Sprintf("GOT DIFF"))
		joblist := runJobs(diff)
		for _, job := range joblist {
			s.Log(fmt.Sprintf("RUNNING %v", job))
			runJob(job, chooseServer(job, checker))
			s.Log(fmt.Sprintf("RAN"))
		}
	}
}

// SetMaster sets up the master settings
func (s Server) SetMaster() {
	checker := &mainChecker{}
	for s.serving {
		time.Sleep(intentWait)

		log.Printf("Running SetMaster")

		fleet := checker.discover()
		matcher := make(map[string]*pbd.RegistryEntry)
		for _, entry := range fleet.GetServices() {
			if _, ok := matcher[entry.GetName()]; !ok {
				matcher[entry.GetName()] = entry
			} else {
				if entry.GetMaster() {
					matcher[entry.GetName()] = entry
				}
			}
		}

		for _, entry := range matcher {
			if !entry.GetMaster() {
				entry.Master = true
				checker.master(entry)
			}
		}
	}
}

func main() {
	config, err := loadConfig("config.pb")
	if err != nil {
		log.Fatalf("Fatal loading of config: %v", err)
	}

	var sync = flag.Bool("once", false, "One pass intent match")
	t := time.Now()
	s := Server{&goserver.GoServer{}, config, true, &t}

	var quiet = flag.Bool("quiet", true, "Show all output")
	flag.Parse()

	if *quiet {
		log.SetFlags(0)
		log.SetOutput(ioutil.Discard)
	}

	if *sync {
		s.MatchIntent()
	} else {
		s.Register = s
		s.PrepServer()
		s.GoServer.Killme = false
		s.RegisterServer("gobuildmaster", false)
		s.RegisterServingTask(s.MatchIntent)
		s.RegisterServingTask(s.SetMaster)
		s.Serve()
	}
}
<commit_msg>More logging<commit_after>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"strconv"
	"time"

	"github.com/brotherlogic/goserver"
	"golang.org/x/net/context"
	"google.golang.org/grpc"

	pbd "github.com/brotherlogic/discovery/proto"
	pb "github.com/brotherlogic/gobuildmaster/proto"
	pbs "github.com/brotherlogic/gobuildslave/proto"
	pbg "github.com/brotherlogic/goserver/proto"
	"github.com/brotherlogic/goserver/utils"
)

const (
	intentWait = time.Second
)

// Server the main server type
type Server struct {
	*goserver.GoServer
	config     *pb.Config
	serving    bool
	lastIntent *time.Time
}

type mainChecker struct {
	prev []string
}

func getIP(servertype, servername string) (string, int) {
	conn, err := grpc.Dial(utils.RegistryIP+":"+strconv.Itoa(utils.RegistryPort), grpc.WithInsecure())
	log.Printf("Error? %v", err)
	defer conn.Close()

	registry := pbd.NewDiscoveryServiceClient(conn)
	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	defer cancel()
	r, err := registry.ListAllServices(ctx, &pbd.Empty{}, grpc.FailFast(false))
	if err != nil {
		return "", -1
	}
	for _, s := range r.Services {
		if s.Name == servertype && s.Identifier == servername {
			return s.Ip, int(s.Port)
		}
	}

	return "", -1
}

func (t *mainChecker) getprev() []string {
	return t.prev
}
func (t *mainChecker) setprev(v []string) {
	t.prev = v
}

func (t *mainChecker) assess(server string) (*pbs.JobList, *pbs.Config) {
	list := &pbs.JobList{}
	conf := &pbs.Config{}

	ip, port := getIP("gobuildslave", server)
	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	defer cancel()
	conn, err := grpc.DialContext(ctx, ip+":"+strconv.Itoa(port), grpc.WithInsecure())
	if err != nil {
		return list, conf
	}
	defer conn.Close()

	slave := pbs.NewGoBuildSlaveClient(conn)
	r, err := slave.List(ctx, &pbs.Empty{}, grpc.FailFast(false))
	if err != nil {
		return list, conf
	}

	r2, err := slave.GetConfig(ctx, &pbs.Empty{}, grpc.FailFast(false))
	if err != nil {
		return list, conf
	}

	return r, r2
}

func (t *mainChecker) master(entry *pbd.RegistryEntry) {
	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	defer cancel()
	conn, _ := grpc.DialContext(ctx, entry.GetIp()+":"+strconv.Itoa(int(entry.GetPort())), grpc.WithInsecure())
	defer conn.Close()

	server := pbg.NewGoserverServiceClient(conn)
	log.Printf("SETTING MASTER: %v", entry)
	_, err := server.Mote(ctx, &pbg.MoteRequest{Master: entry.GetMaster()}, grpc.FailFast(false))
	if err != nil {
		log.Printf("RESPONSE: %v", err)
	}
}

func runJob(job *pbs.JobSpec, server string) {
	log.Printf("Run %v on %v", job.Name, server)
	if server != "" {
		ip, port := getIP("gobuildslave", server)
		ctx, cancel := context.WithTimeout(context.Background(), time.Second)
		defer cancel()
		conn, _ := grpc.DialContext(ctx, ip+":"+strconv.Itoa(port), grpc.WithInsecure())
		defer conn.Close()

		slave := pbs.NewGoBuildSlaveClient(conn)
		job.Server = server
		slave.Run(ctx, job, grpc.FailFast(false))
	}
}

func (t *mainChecker) discover() *pbd.ServiceList {
	ret := &pbd.ServiceList{}

	conn, _ := grpc.Dial(utils.RegistryIP+":"+strconv.Itoa(utils.RegistryPort), grpc.WithInsecure())
	defer conn.Close()

	registry := pbd.NewDiscoveryServiceClient(conn)
	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	defer cancel()
	r, err := registry.ListAllServices(ctx, &pbd.Empty{}, grpc.FailFast(false))
	if err == nil {
		for _, s := range r.Services {
			ret.Services = append(ret.Services, s)
		}
	}

	return ret
}

// DoRegister Registers this server
func (s Server) DoRegister(server *grpc.Server) {
	pb.RegisterGoBuildMasterServer(server, &s)
}

// ReportHealth determines if the server is healthy
func (s Server) ReportHealth() bool {
	return true
}

// Mote promotes/demotes this server
func (s Server) Mote(master bool) error {
	return nil
}

//GetState gets the state of the server
func (s Server) GetState() []*pbg.State {
	return []*pbg.State{&pbg.State{Key: "last_intent", TimeValue: s.lastIntent.Unix()}}
}

//Compare compares current state to desired state
func (s Server) Compare(ctx context.Context, in *pb.Empty) (*pb.CompareResponse, error) {
	resp := &pb.CompareResponse{}
	list, _ := getFleetStatus(&mainChecker{})
	cc := &pb.Config{}
	for _, jlist := range list {
		for _, job := range jlist.GetDetails() {
			cc.Intents = append(cc.Intents, &pb.Intent{Spec: job.GetSpec()})
		}
	}
	resp.Current = cc
	resp.Desired = s.config

	return resp, nil
}

func getConfig(c checker) *pb.Config {
	list, _ := getFleetStatus(c)
	config := &pb.Config{}

	for _, jlist := range list {
		for _, job := range jlist.Details {
			found := false
			for _, ij := range config.Intents {
				if job.Spec.Name == ij.Spec.Name {
					ij.Count++
					found = true
				}
			}

			if !found {
				config.Intents = append(config.Intents, &pb.Intent{Spec: &pbs.JobSpec{Name: job.Spec.Name}, Count: 1})
			}
		}
	}

	return config
}

// MatchIntent tries to match the intent with the state of production
func (s *Server) MatchIntent() {
	checker := &mainChecker{}
	for s.serving {
		s.Log(fmt.Sprintf("MATCHING %v", s.serving))
		time.Sleep(intentWait)
		t := time.Now()
		s.lastIntent = &t
		s.Log(fmt.Sprintf("SETTING INTENT:%v", t))

		state := getConfig(checker)
		s.Log(fmt.Sprintf("GOT CONFIG"))
		diff := configDiff(s.config, state)
		s.Log(fmt.Sprintf("GOT DIFF"))
		joblist := runJobs(diff)
		for _, job := range joblist {
			s.Log(fmt.Sprintf("RUNNING %v", job))
			runJob(job, chooseServer(job, checker))
			s.Log(fmt.Sprintf("RAN"))
		}
	}
}

// SetMaster sets up the master settings
func (s Server) SetMaster() {
	checker := &mainChecker{}
	for s.serving {
		time.Sleep(intentWait)

		log.Printf("Running SetMaster")

		fleet := checker.discover()
		matcher := make(map[string]*pbd.RegistryEntry)
		for _, entry := range fleet.GetServices() {
			if _, ok := matcher[entry.GetName()]; !ok {
				matcher[entry.GetName()] = entry
			} else {
				if entry.GetMaster() {
					matcher[entry.GetName()] = entry
				}
			}
		}

		for _, entry := range matcher {
			if !entry.GetMaster() {
				entry.Master = true
				checker.master(entry)
			}
		}
	}
}

func main() {
	config, err := loadConfig("config.pb")
	if err != nil {
		log.Fatalf("Fatal loading of config: %v", err)
	}

	var sync = flag.Bool("once", false, "One pass intent match")
	t := time.Now()
	s := Server{&goserver.GoServer{}, config, true, &t}

	var quiet = flag.Bool("quiet", true, "Show all output")
	flag.Parse()

	if *quiet {
		log.SetFlags(0)
		log.SetOutput(ioutil.Discard)
	}

	if *sync {
		s.MatchIntent()
	} else {
		s.Register = s
		s.PrepServer()
		s.GoServer.Killme = false
		s.RegisterServer("gobuildmaster", false)
		s.RegisterServingTask(s.MatchIntent)
		s.RegisterServingTask(s.SetMaster)
		s.Serve()
	}
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"crypto/rand"
	"encoding/json"
	"errors"
	"fmt"
	ggproto "github.com/gogo/protobuf/proto"
	gopass "github.com/howeyc/gopass"
	b58 "github.com/jbenet/go-base58"
	p2p_crypto "github.com/libp2p/go-libp2p-crypto"
	mc "github.com/mediachain/concat/mc"
	pb "github.com/mediachain/concat/proto"
	homedir "github.com/mitchellh/go-homedir"
	sbox "golang.org/x/crypto/nacl/secretbox"
	scrypt "golang.org/x/crypto/scrypt"
	kp "gopkg.in/alecthomas/kingpin.v2"
	"io/ioutil"
	"log"
	"os"
	"path"
	"time"
)

func main() {
	log.SetFlags(0) // naked logs, it's interactive output

	var (
		home = kp.Flag("home", "mcid home directory").Short('d').Default("~/.mediachain/mcid").String()

		_ = kp.Command("id", "show your public identity; generates a new key pair if it doesn't already exist.") // idCmd declared but not used

		signCmd      = kp.Command("sign", "sign a manifest")
		signEntity   = signCmd.Arg("entity", "entity id").Required().String()
		signManifest = signCmd.Arg("manifest", "manifest json file").Required().File()

		verifyCmd      = kp.Command("verify", "verify a manifest")
		verifyManifest = verifyCmd.Arg("manifest", "manifest json file").Required().ExistingFile()
	)

	switch kp.Parse() {
	case "id":
		doId(*home)

	case "sign":
		doSign(*home, *signEntity, *signManifest)

	case "verify":
		doVerify(*home, *verifyManifest)
	}
}

type Identity struct {
	Public  PublicId  `json:"public"`
	Private PrivateId `json:"private"`
}

type PublicId struct {
	KeyId string `json:"keyId"` // public key multihash
	Key   []byte `json:"key"`   // marshalled public key
}

type PrivateId struct {
	Params ScryptParams `json:"params"` // key derivation parameters
	Salt   []byte       `json:"salt"`   // key derivation salt
	Nonce  []byte       `json:"nonce"`  // encryption nonce
	Data   []byte       `json:"data"`   // encrypted marshalled private key
}

type ScryptParams struct {
	N, R, P int
}

// default scrypt parameters (2009): N=16384, r=8, p=1
// still current; see https://github.com/Tarsnap/scrypt/issues/19
const (
	ScryptN = 16384
	ScryptR = 8
	ScryptP = 1
)

var (
	DecryptionError = errors.New("Private key decryption failed")
)

// ops
func doId(home string) {
	id, err := getIdentity(home, true) // generate id if it doesn't already exist
	if err != nil {
		log.Fatalf("Error retrieving identity: %s", err.Error())
	}

	json.NewEncoder(os.Stdout).Encode(id.Public)
}

func doSign(home string, entity string, mf *os.File) {
	var manifest pb.Manifest
	var manifestBody pb.ManifestBody

	err := json.NewDecoder(mf).Decode(&manifestBody)
	if err != nil {
		log.Fatalf("Error decoding manifest body: %s", err.Error())
	}

	id, err := getIdentity(home, false) // error if id doesn't exist
	if err != nil {
		log.Fatalf("Error retrieving identity: %s", err.Error())
	}

	privk, err := getPrivateKey(id.Private)
	if err != nil {
		log.Fatalf("Error decrypting private key: %s", err.Error())
	}

	manifest.Entity = entity
	manifest.KeyId = id.Public.KeyId
	manifest.Body = &manifestBody
	manifest.Timestamp = time.Now().Unix()

	bytes, err := ggproto.Marshal(&manifest)
	if err != nil {
		log.Fatalf("Error marshalling manifest: %s", err.Error())
	}

	sig, err := privk.Sign(bytes)
	if err != nil {
		log.Fatalf("Error signing manifest: %s", err.Error())
	}

	manifest.Signature = sig

	json.NewEncoder(os.Stdout).Encode(&manifest)
}

func doVerify(home string, manifest string) {
	log.Fatalf("IMPLEMENT ME: doVerify %s %s\n", home, manifest)
}

// identity
func getIdentity(home string, genid bool) (id Identity, err error) {
	home, err = homedir.Expand(home)
	if err != nil {
		return
	}

	idpath := path.Join(home, "identity.json")
	_, err = os.Stat(idpath)
	switch {
	case os.IsNotExist(err):
		if genid {
			return generateIdentity(home, idpath)
		}
		fallthrough
	case err != nil:
		return

	default:
		return loadIdentity(idpath)
	}
}

func generateIdentity(home, idpath string) (id Identity, err error) {
	err = os.MkdirAll(home, 0755)
	if err != nil {
		return
	}

	log.Printf("Generating identity key pair")
	privk, pubk, err := mc.GenerateECCKeyPair()
	if err != nil {
		return
	}

	pubbytes, err := pubk.Bytes()
	if err != nil {
		return
	}
	kid := b58.Encode(mc.Hash(pubbytes))

	id.Public.KeyId = kid
	id.Public.Key = pubbytes

	privbytes, err := privk.Bytes()
	if err != nil {
		return
	}

	err = encryptPrivateId(&id.Private, privbytes)
	if err != nil {
		return
	}

	bytes, err := json.Marshal(&id)
	if err != nil {
		return
	}

	err = ioutil.WriteFile(idpath, bytes, 0600)
	return
}

func loadIdentity(idpath string) (id Identity, err error) {
	bytes, err := ioutil.ReadFile(idpath)
	if err != nil {
		return
	}

	err = json.Unmarshal(bytes, &id)
	return
}

func getPrivateKey(priv PrivateId) (p2p_crypto.PrivKey, error) {
	bytes, err := decryptPrivateId(priv)
	if err != nil {
		return nil, err
	}

	return p2p_crypto.UnmarshalPrivateKey(bytes)
}

// private key encryption/decryption:
//  key derivation with scrypt
//  encryption with nacl secretbox
func encryptPrivateId(priv *PrivateId, data []byte) error {
	var (
		salt  [16]byte
		nonce [24]byte
		key   [32]byte
	)

	_, err := rand.Read(salt[:])
	if err != nil {
		return err
	}

	_, err = rand.Read(nonce[:])
	if err != nil {
		return err
	}

	pass, err := getEncryptionPass()
	if err != nil {
		return err
	}

	xkey, err := scrypt.Key(pass, salt[:], ScryptN, ScryptR, ScryptP, 32)
	if err != nil {
		return err
	}

	copy(key[:], xkey)

	ctext := sbox.Seal(nil, data, &nonce, &key)

	priv.Salt = salt[:]
	priv.Nonce = nonce[:]
	priv.Data = ctext[:]
	priv.Params.N = ScryptN
	priv.Params.R = ScryptR
	priv.Params.P = ScryptP

	return nil
}

func decryptPrivateId(priv PrivateId) ([]byte, error) {
	var (
		nonce [24]byte
		key   [32]byte
	)

	pass, err := getDecryptionPass()
	if err != nil {
		return nil, err
	}

	xkey, err := scrypt.Key(pass, priv.Salt, priv.Params.N, priv.Params.R, priv.Params.P, 32)
	if err != nil {
		return nil, err
	}

	copy(nonce[:], priv.Nonce)
	copy(key[:], xkey)

	bytes, ok := sbox.Open(nil, priv.Data, &nonce, &key)
	if !ok {
		return nil, DecryptionError
	}

	return bytes, nil
}

func getEncryptionPass() ([]byte, error) {
	for {
		fmt.Printf("Enter passphrase: ")
		pass1, err := gopass.GetPasswd()
		if err != nil {
			return nil, err
		}

		fmt.Printf("Re-enter passphrase: ")
		pass2, err := gopass.GetPasswd()
		if err != nil {
			return nil, err
		}

		if bytes.Equal(pass1, pass2) {
			return pass1, nil
		}

		fmt.Println("Passphrases don't match")
	}
}

func getDecryptionPass() ([]byte, error) {
	fmt.Printf("Enter passphrase: ")
	return gopass.GetPasswd()
}
<commit_msg>mcid: use jsonpb for manifest json encoding/decoding<commit_after>package main

import (
	"bytes"
	"crypto/rand"
	"encoding/json"
	"errors"
	"fmt"
	jsonpb "github.com/gogo/protobuf/jsonpb"
	ggproto "github.com/gogo/protobuf/proto"
	gopass "github.com/howeyc/gopass"
	b58 "github.com/jbenet/go-base58"
	p2p_crypto "github.com/libp2p/go-libp2p-crypto"
	mc "github.com/mediachain/concat/mc"
	pb "github.com/mediachain/concat/proto"
	homedir "github.com/mitchellh/go-homedir"
	sbox "golang.org/x/crypto/nacl/secretbox"
	scrypt "golang.org/x/crypto/scrypt"
	kp "gopkg.in/alecthomas/kingpin.v2"
	"io/ioutil"
	"log"
	"os"
	"path"
	"time"
)

func main() {
	log.SetFlags(0) // naked logs, it's interactive output

	var (
		home = kp.Flag("home", "mcid home directory").Short('d').Default("~/.mediachain/mcid").String()

		_ = kp.Command("id", "show your public identity; generates a new key pair if it doesn't already exist.") // idCmd declared but not used

		signCmd      = kp.Command("sign", "sign a manifest")
		signEntity   = signCmd.Arg("entity", "entity id").Required().String()
		signManifest = signCmd.Arg("manifest", "manifest json file").Required().File()

		verifyCmd      = kp.Command("verify", "verify a manifest")
		verifyManifest = verifyCmd.Arg("manifest", "manifest json file").Required().ExistingFile()
	)

	switch kp.Parse() {
	case "id":
		doId(*home)

	case "sign":
		doSign(*home, *signEntity, *signManifest)

	case "verify":
		doVerify(*home, *verifyManifest)
	}
}

type Identity struct {
	Public  PublicId  `json:"public"`
	Private PrivateId `json:"private"`
}

type PublicId struct {
	KeyId string `json:"keyId"` // public key multihash
	Key   []byte `json:"key"`   // marshalled public key
}

type PrivateId struct {
	Params ScryptParams `json:"params"` // key derivation parameters
	Salt   []byte       `json:"salt"`   // key derivation salt
	Nonce  []byte       `json:"nonce"`  // encryption nonce
	Data   []byte       `json:"data"`   // encrypted marshalled private key
}

type ScryptParams struct {
	N, R, P int
}

// default scrypt parameters (2009): N=16384, r=8, p=1
// still current; see https://github.com/Tarsnap/scrypt/issues/19
const (
	ScryptN = 16384
	ScryptR = 8
	ScryptP = 1
)

var (
	DecryptionError = errors.New("Private key decryption failed")
)

// ops
func doId(home string) {
	id, err := getIdentity(home, true) // generate id if it doesn't already exist
	if err != nil {
		log.Fatalf("Error retrieving identity: %s", err.Error())
	}

	json.NewEncoder(os.Stdout).Encode(id.Public)
}

func doSign(home string, entity string, mf *os.File) {
	var manifest pb.Manifest
	var manifestBody pb.ManifestBody

	err := jsonpb.Unmarshal(mf, &manifestBody)
	if err != nil {
		log.Fatalf("Error decoding manifest body: %s", err.Error())
	}

	id, err := getIdentity(home, false) // error if id doesn't exist
	if err != nil {
		log.Fatalf("Error retrieving identity: %s", err.Error())
	}

	privk, err := getPrivateKey(id.Private)
	if err != nil {
		log.Fatalf("Error decrypting private key: %s", err.Error())
	}

	manifest.Entity = entity
	manifest.KeyId = id.Public.KeyId
	manifest.Body = &manifestBody
	manifest.Timestamp = time.Now().Unix()

	bytes, err := ggproto.Marshal(&manifest)
	if err != nil {
		log.Fatalf("Error marshalling manifest: %s", err.Error())
	}

	sig, err := privk.Sign(bytes)
	if err != nil {
		log.Fatalf("Error signing manifest: %s", err.Error())
	}

	manifest.Signature = sig

	marshaler := jsonpb.Marshaler{}
	err = marshaler.Marshal(os.Stdout, &manifest)
	if err != nil {
		log.Fatalf("Error encoding manifest: %s", err.Error())
	}
	fmt.Println("")
}

func doVerify(home string, manifest string) {
	log.Fatalf("IMPLEMENT ME: doVerify %s %s\n", home, manifest)
}

// identity
func getIdentity(home string, genid bool) (id Identity, err error) {
	home, err = homedir.Expand(home)
	if err != nil {
		return
	}

	idpath := path.Join(home, "identity.json")
	_, err = os.Stat(idpath)
	switch {
	case os.IsNotExist(err):
		if genid {
			return generateIdentity(home, idpath)
		}
		fallthrough
	case err != nil:
		return

	default:
		return loadIdentity(idpath)
	}
}

func generateIdentity(home, idpath string) (id Identity, err error) {
	err = os.MkdirAll(home, 0755)
	if err != nil {
		return
	}

	log.Printf("Generating identity key pair")
	privk, pubk, err := mc.GenerateECCKeyPair()
	if err != nil {
		return
	}

	pubbytes, err := pubk.Bytes()
	if err != nil {
		return
	}
	kid := b58.Encode(mc.Hash(pubbytes))

	id.Public.KeyId = kid
	id.Public.Key = pubbytes

	privbytes, err := privk.Bytes()
	if err != nil {
		return
	}

	err = encryptPrivateId(&id.Private, privbytes)
	if err != nil {
		return
	}

	bytes, err := json.Marshal(&id)
	if err != nil {
		return
	}

	err = ioutil.WriteFile(idpath, bytes, 0600)
	return
}

func loadIdentity(idpath string) (id Identity, err error) {
	bytes, err := ioutil.ReadFile(idpath)
	if err != nil {
		return
	}

	err = json.Unmarshal(bytes, &id)
	return
}

func getPrivateKey(priv PrivateId) (p2p_crypto.PrivKey, error) {
	bytes, err := decryptPrivateId(priv)
	if err != nil {
		return nil, err
	}

	return p2p_crypto.UnmarshalPrivateKey(bytes)
}

// private key encryption/decryption:
//  key derivation with scrypt
//  encryption with nacl secretbox
func encryptPrivateId(priv *PrivateId, data []byte) error {
	var (
		salt  [16]byte
		nonce [24]byte
		key   [32]byte
	)

	_, err := rand.Read(salt[:])
	if err != nil {
		return err
	}

	_, err = rand.Read(nonce[:])
	if err != nil {
		return err
	}

	pass, err := getEncryptionPass()
	if err != nil {
		return err
	}

	xkey, err := scrypt.Key(pass, salt[:], ScryptN, ScryptR, ScryptP, 32)
	if err != nil {
		return err
	}

	copy(key[:], xkey)

	ctext := sbox.Seal(nil, data, &nonce, &key)

	priv.Salt = salt[:]
	priv.Nonce = nonce[:]
	priv.Data = ctext[:]
	priv.Params.N = ScryptN
	priv.Params.R = ScryptR
	priv.Params.P = ScryptP

	return nil
}

func decryptPrivateId(priv PrivateId) ([]byte, error) {
	var (
		nonce [24]byte
		key   [32]byte
	)

	pass, err := getDecryptionPass()
	if err != nil {
		return nil, err
	}

	xkey, err := scrypt.Key(pass, priv.Salt, priv.Params.N, priv.Params.R, priv.Params.P, 32)
	if err != nil {
		return nil, err
	}

	copy(nonce[:], priv.Nonce)
	copy(key[:], xkey)

	bytes, ok := sbox.Open(nil, priv.Data, &nonce, &key)
	if !ok {
		return nil, DecryptionError
	}

	return bytes, nil
}

func getEncryptionPass() ([]byte, error) {
	for {
		fmt.Printf("Enter passphrase: ")
		pass1, err := gopass.GetPasswd()
		if err != nil {
			return nil, err
		}

		fmt.Printf("Re-enter passphrase: ")
		pass2, err := gopass.GetPasswd()
		if err != nil {
			return nil, err
		}

		if bytes.Equal(pass1, pass2) {
			return pass1, nil
		}

		fmt.Println("Passphrases don't match")
	}
}

func getDecryptionPass() ([]byte, error) {
	fmt.Printf("Enter passphrase: ")
	return gopass.GetPasswd()
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
)

func main() {
	resp, err := http.Get("http://")
	if err != nil {
		fmt.Println("network error")
		fmt.Println(err.Error())
		return
	}

	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("io error")
		fmt.Println(err.Error())
		return
	}

	fmt.Println(string(body))
}
<commit_msg>http get<commit_after>package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
)

/**
*http://blog.csdn.net/kenkao/article/details/47857757
 */
func main() {
	resp, err := http.Get("http://")
	if err != nil {
		fmt.Println("network error")
		fmt.Println(err.Error())
		return
	}

	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("io error")
		fmt.Println(err.Error())
		return
	}

	fmt.Println(string(body))
}
<|endoftext|>


<commit_before>package ssm

import (
	"fmt"
	"github.com/aws/aws-sdk-go/service/ssm"
	"github.com/viant/endly"
	"github.com/viant/endly/system/cloud/aws"
	"log"
)

const (
	//ServiceID aws Simple Systems Manager ID.
	ServiceID = "aws/ssm"
)

//no operation service
type service struct {
	*endly.AbstractService
}

func (s *service) registerRoutes() {
	client := &ssm.SSM{}
	routes, err := aws.BuildRoutes(client, getClient)
	if err != nil {
		log.Printf("unable register service %v actions: %v\n", ServiceID, err)
		return
	}
	for _, route := range routes {
		route.OnRawRequest = setClient
		s.Register(route)
	}

	s.Register(&endly.Route{
		Action: "setParameter",
		RequestInfo: &endly.ActionInfo{
			Description: fmt.Sprintf("%T.%v(%T)", s, "setParameter", &SetParameterInput{}),
		},
		ResponseInfo: &endly.ActionInfo{
			Description: fmt.Sprintf("%T", &ssm.PutParameterOutput{}),
		},
		RequestProvider: func() interface{} {
			return &SetParameterInput{}
		},
		ResponseProvider: func() interface{} {
			return &ssm.PutParameterOutput{}
		},
		OnRawRequest: setClient,
		Handler: func(context *endly.Context, request interface{}) (interface{}, error) {
			if req, ok := request.(*SetParameterInput); ok {
				resp, err := s.setParameter(context, req)
				if err == nil {
					if context.IsLoggingEnabled() {
						context.Publish(aws.NewOutputEvent("setParameter", "proxy", resp))
					}
				}
				return resp, err
			}
			return nil, fmt.Errorf("unsupported request type: %T", request)
		},
	})
}

func (s *service) setParameter(context *endly.Context, input *SetParameterInput) (*ssm.PutParameterOutput, error) {
	client, err := GetClient(context)
	if err != nil {
		return nil, err
	}
	withDecryption := true
	getOutput, err := client.GetParameter(&ssm.GetParameterInput{
		Name:           input.Name,
		WithDecryption: &withDecryption,
	})

	found := err == nil && getOutput != nil

	if found && *getOutput.Parameter.Value == *input.Value {
		return &ssm.PutParameterOutput{
			Version: getOutput.Parameter.Version,
		}, nil
	}
	putParameter := ssm.PutParameterInput(*input)
	return client.PutParameter(&putParameter)
}

//New creates a new AWS Simple Systems Manager service.
func New() endly.Service {
	var result = &service{
		AbstractService: endly.NewAbstractService(ServiceID),
	}
	result.AbstractService.Service = result
	result.registerRoutes()
	return result
}
<commit_msg>updated error handling<commit_after>package ssm

import (
	"fmt"
	"github.com/aws/aws-sdk-go/service/ssm"
	"github.com/pkg/errors"
	"github.com/viant/endly"
	"github.com/viant/endly/system/cloud/aws"
	"log"
)

const (
	//ServiceID aws Simple Systems Manager ID.
	ServiceID = "aws/ssm"
)

//no operation service
type service struct {
	*endly.AbstractService
}

func (s *service) registerRoutes() {
	client := &ssm.SSM{}
	routes, err := aws.BuildRoutes(client, getClient)
	if err != nil {
		log.Printf("unable register service %v actions: %v\n", ServiceID, err)
		return
	}
	for _, route := range routes {
		route.OnRawRequest = setClient
		s.Register(route)
	}

	s.Register(&endly.Route{
		Action: "setParameter",
		RequestInfo: &endly.ActionInfo{
			Description: fmt.Sprintf("%T.%v(%T)", s, "setParameter", &SetParameterInput{}),
		},
		ResponseInfo: &endly.ActionInfo{
			Description: fmt.Sprintf("%T", &ssm.PutParameterOutput{}),
		},
		RequestProvider: func() interface{} {
			return &SetParameterInput{}
		},
		ResponseProvider: func() interface{} {
			return &ssm.PutParameterOutput{}
		},
		OnRawRequest: setClient,
		Handler: func(context *endly.Context, request interface{}) (interface{}, error) {
			if req, ok := request.(*SetParameterInput); ok {
				resp, err := s.setParameter(context, req)
				if err == nil {
					if context.IsLoggingEnabled() {
						context.Publish(aws.NewOutputEvent("setParameter", "proxy", resp))
					}
				}
				return resp, err
			}
			return nil, fmt.Errorf("unsupported request type: %T", request)
		},
	})
}

func (s *service) setParameter(context *endly.Context, input *SetParameterInput) (*ssm.PutParameterOutput, error) {
	client, err := GetClient(context)
	if err != nil {
		return nil, err
	}
	withDecryption := true
	*input.Name = context.Expand(*input.Name)
	*input.Value = context.Expand(*input.Value)

	getOutput, err := client.GetParameter(&ssm.GetParameterInput{
		Name:           input.Name,
		WithDecryption: &withDecryption,
	})
	found := err == nil && getOutput != nil
	if found && *getOutput.Parameter.Value == *input.Value {
		return &ssm.PutParameterOutput{
			Version: getOutput.Parameter.Version,
		}, nil
	}

	putParameter := ssm.PutParameterInput(*input)

	output, err := client.PutParameter(&putParameter)
	if err != nil {
		err = errors.Wrapf(err, "failed to put parameters: %v", putParameter)
	}
	return output, err
}

//New creates a new AWS Simple Systems Manager service.
func New() endly.Service {
	var result = &service{
		AbstractService: endly.NewAbstractService(ServiceID),
	}
	result.AbstractService.Service = result
	result.registerRoutes()
	return result
}
<|endoftext|>


<commit_before>package pop3

import (
	"bufio"
	"bytes"
	"io"
	"net"
	"strings"
	"testing"
	"time"
)

type fakeAddr struct {}
func (fakeAddr) Network() string { return "" }
func (fakeAddr) String() string { return "" }

type faker struct {
	io.ReadWriter
}

func (f faker) Close() error {
	return nil
}

func (f faker) LocalAddr() net.Addr {
	return fakeAddr{}
}

func (f faker) RemoteAddr() net.Addr {
	return fakeAddr{}
}

func (f faker) SetDeadline(t time.Time) error {
	return nil
}

func (f faker) SetReadDeadline(t time.Time) error {
	return nil
}

func (f faker) SetWriteDeadline(t time.Time) error {
	return nil
}

func TestBasic (t *testing.T) {
	basicServer := strings.Join(strings.Split(basicServer, "\n"), "\r\n")
	basicClient := strings.Join(strings.Split(basicClient, "\n"), "\r\n")

	var cmdbuf bytes.Buffer
	bcmdbuf := bufio.NewWriter(&cmdbuf)
	var fake faker
	fake.ReadWriter = bufio.NewReadWriter(bufio.NewReader(strings.NewReader(basicServer)), bcmdbuf)

	_, err := NewClient(fake)
	if err != nil {
		t.Fatalf("NewClient failed: %s", err)
	}

	bcmdbuf.Flush()
	if basicClient != cmdbuf.String() {
		t.Fatalf("Got:\n%s\nExpected:\n%s", cmdbuf.String(), basicClient)
	}
}

var basicServer = `+OK good morning
`

var basicClient = ``
<commit_msg>Testing User and Pass<commit_after>package pop3

import (
	"bufio"
	"bytes"
	"io"
	"net"
	"strings"
	"testing"
	"time"
)

type fakeAddr struct {}
func (fakeAddr) Network() string { return "" }
func (fakeAddr) String() string { return "" }

type faker struct {
	io.ReadWriter
}

func (f faker) Close() error {
	return nil
}

func (f faker) LocalAddr() net.Addr {
	return fakeAddr{}
}

func (f faker) RemoteAddr() net.Addr {
	return fakeAddr{}
}

func (f faker) SetDeadline(t time.Time) error {
	return nil
}

func (f faker) SetReadDeadline(t time.Time) error {
	return nil
}

func (f faker) SetWriteDeadline(t time.Time) error {
	return nil
}

func TestBasic (t *testing.T) {
	basicServer := strings.Join(strings.Split(basicServer, "\n"), "\r\n")
	basicClient := strings.Join(strings.Split(basicClient, "\n"), "\r\n")

	var cmdbuf bytes.Buffer
	bcmdbuf := bufio.NewWriter(&cmdbuf)
	var fake faker
	fake.ReadWriter = bufio.NewReadWriter(bufio.NewReader(strings.NewReader(basicServer)), bcmdbuf)

	c, err := NewClient(fake)
	if err != nil {
		t.Fatalf("NewClient failed: %s", err)
	}

	if err = c.User("uname"); err != nil {
		t.Fatal("User failed: %s", err)
	}

	if err = c.Pass("password"); err != nil {
		t.Fatal("Pass failed: %s", err)
	}

	bcmdbuf.Flush()
	if basicClient != cmdbuf.String() {
		t.Fatalf("Got:\n%s\nExpected:\n%s", cmdbuf.String(), basicClient)
	}
}

var basicServer = `+OK good morning
+OK
+OK
`

var basicClient = `USER uname
PASS password
`
<|endoftext|>


<commit_before>package comments

import (
	"io/ioutil"
	"testing"

	"github.com/parkr/auto-reply/Godeps/_workspace/src/github.com/stretchr/testify/assert"
)

func TestParseMergeRequestComment(t *testing.T) {
	comments := []struct {
		comment string
		isReq   bool
		label   string
	}{
		{"it looked like you could merge it", false, ""},
		{"@jekyllbot: merge", true, ""},
		{"@jekyllbot: :shipit:", true, ""},
		{"@jekyllbot: :ship:", true, ""},
		{"@jekyllbot: merge +Site", true, "site-enhancements"},
		{"@jekyllbot: merge +minor-enhancement", true, "minor-enhancements"},
		{"@jekyllbot: merge +Bug Fix\n", true, "bug-fixes"},
	}
	for _, c := range comments {
		isReq, label := parseMergeRequestComment(c.comment)
		assert.Equal(t, c.isReq, isReq, "'%s' should have isReq=%v", c.comment, c.isReq)
		assert.Equal(t, c.label, label, "'%s' should have label=%v", c.comment, c.label)
	}
}

func TestBase64Decode(t *testing.T) {
	encoded, err := ioutil.ReadFile("history_contents.enc")
	assert.NoError(t, err)
	decoded := base64Decode(string(encoded))
	assert.Contains(t, decoded, "### Minor Enhancements")
}

func TestAddMergeReference(t *testing.T) {
	historyFile := addMergeReference("", "Development Fixes", "Some great change", 1)
	assert.Equal(t, "## HEAD\n\n### Development Fixes\n\n  * Some great change (#1)\n", historyFile)

	historyFile = addMergeReference(
		"## HEAD",
		"Development Fixes", "Another great change!!!!!!!", 1)
	assert.Equal(t, "## HEAD\n\n### Development Fixes\n\n  * Another great change!!!!!!! (#1)\n", historyFile)

	historyFile = addMergeReference(
		"## HEAD\n\n### Development Fixes\n\n  * Some great change (#1)\n",
		"Development Fixes", "Another great change!!!!!!!", 1)
	assert.Equal(t, "## HEAD\n\n### Development Fixes\n\n  * Some great change (#1)\n  * Another great change!!!!!!! (#1)\n", historyFile)
}
<commit_msg>comments: ensure addMergeReference works<commit_after>package comments

import (
	"io/ioutil"
	"testing"

	"github.com/parkr/auto-reply/Godeps/_workspace/src/github.com/stretchr/testify/assert"
)

func TestParseMergeRequestComment(t *testing.T) {
	comments := []struct {
		comment string
		isReq   bool
		label   string
	}{
		{"it looked like you could merge it", false, ""},
		{"@jekyllbot: merge", true, ""},
		{"@jekyllbot: :shipit:", true, ""},
		{"@jekyllbot: :ship:", true, ""},
		{"@jekyllbot: merge +Site", true, "site-enhancements"},
		{"@jekyllbot: merge +minor-enhancement", true, "minor-enhancements"},
		{"@jekyllbot: merge +Bug Fix\n", true, "bug-fixes"},
	}
	for _, c := range comments {
		isReq, label := parseMergeRequestComment(c.comment)
		assert.Equal(t, c.isReq, isReq, "'%s' should have isReq=%v", c.comment, c.isReq)
		assert.Equal(t, c.label, label, "'%s' should have label=%v", c.comment, c.label)
	}
}

func TestBase64Decode(t *testing.T) {
	encoded, err := ioutil.ReadFile("history_contents.enc")
	assert.NoError(t, err)
	decoded := base64Decode(string(encoded))
	assert.Contains(t, decoded, "### Minor Enhancements")
}

func TestAddMergeReference(t *testing.T) {
	historyFile := addMergeReference("", "Development Fixes", "Some great change", 1)
	assert.Equal(t, "## HEAD\n\n### Development Fixes\n\n  * Some great change (#1)\n", historyFile)

	historyFile = addMergeReference(
		"## HEAD",
		"Development Fixes", "Another great change!!!!!!!", 1)
	assert.Equal(t, "## HEAD\n\n### Development Fixes\n\n  * Another great change!!!!!!! (#1)\n", historyFile)

	historyFile = addMergeReference(
		"## HEAD\n\n### Development Fixes\n\n  * Some great change (#1)\n",
		"Development Fixes", "Another great change!!!!!!!", 1)
	assert.Equal(t, "## HEAD\n\n### Development Fixes\n\n  * Some great change (#1)\n  * Another great change!!!!!!! (#1)\n", historyFile)

	jekyllHistory, err := ioutil.ReadFile("History.markdown")
	assert.NoError(t, err)
	historyFile = addMergeReference(string(jekyllHistory), "Development Fixes", "A marvelous change.", 41526)
	assert.Contains(t, historyFile, "* A marvelous change. (#41526)\n\n### Site Enhancements")
}

func TestBase64Encode(t *testing.T) {
	enc := base64Encode("hi")
	assert.Equal(t, "aGk=", string(enc))
}
<|endoftext|>


<commit_before>package main

import (
	"crypto"
	"crypto/x509"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"

	"github.com/bifurcation/mint"
	"github.com/cloudflare/cfssl/helpers"
)

var (
	port       string
	serverName string
	certFile   string
	keyFile    string
)

func main() {
	flag.StringVar(&port, "port", "4430", "port")
	flag.StringVar(&serverName, "host", "example.com", "hostname")
	flag.StringVar(&certFile, "cert", "", "certificate chain in PEM or DER")
	flag.StringVar(&keyFile, "key", "", "private key in PEM format")
	flag.Parse()

	var certChain []*x509.Certificate
	var priv crypto.Signer
	var err error

	if certFile != "" {
		certs, err := ioutil.ReadFile(certFile)
		if err != nil {
			log.Fatalf("Error: %v", err)
		} else {
			certChain, err = helpers.ParseCertificatesPEM(certs)
			if err != nil {
				certChain, _, err = helpers.ParseCertificatesDER(certs, "")
			}
		}
	}
	if keyFile != "" {
		keyPEM, err := ioutil.ReadFile(keyFile)
		if err != nil {
			log.Fatalf("Error: %v", err)
		} else {
			priv, err = helpers.ParsePrivateKeyPEM(keyPEM)
		}
	}
	if err != nil {
		log.Fatalf("Error: %v", err)
	}

	config := mint.Config{
		SendSessionTickets: true,
		ServerName:         serverName,
	}

	if certChain != nil && priv != nil {
		log.Printf("Loading cert: %v key: %v", certFile, keyFile)
		config.Certificates = []*mint.Certificate{
			&mint.Certificate{
				Chain:      certChain,
				PrivateKey: priv,
			},
		}
	}
	config.Init(false)

	service := "0.0.0.0:" + port
	listener, err := mint.Listen("tcp", service, &config)

	if err != nil {
		log.Printf("Error: %v", err)
	}

	http.HandleFunc("/", handleClient)
	s := &http.Server{}
	s.Serve(listener)
}

func handleClient(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintln(w, "Welcome to the TLS 1.3 zone!")
}
<commit_msg>Add support for loading a file from disk.<commit_after>package main

import (
	"crypto"
	"crypto/x509"
	"flag"
	"io/ioutil"
	"log"
	"net/http"

	"github.com/bifurcation/mint"
	"github.com/cloudflare/cfssl/helpers"
)

var (
	port         string
	serverName   string
	certFile     string
	keyFile      string
	responseFile string
)

func main() {
	flag.StringVar(&port, "port", "4430", "port")
	flag.StringVar(&serverName, "host", "example.com", "hostname")
	flag.StringVar(&certFile, "cert", "", "certificate chain in PEM or DER")
	flag.StringVar(&keyFile, "key", "", "private key in PEM format")
	flag.StringVar(&responseFile, "response", "", "file to serve")
	flag.Parse()

	var certChain []*x509.Certificate
	var priv crypto.Signer
	var response []byte
	var err error

	// Load the key and certificate chain
	if certFile != "" {
		certs, err := ioutil.ReadFile(certFile)
		if err != nil {
			log.Fatalf("Error: %v", err)
		} else {
			certChain, err = helpers.ParseCertificatesPEM(certs)
			if err != nil {
				certChain, _, err = helpers.ParseCertificatesDER(certs, "")
			}
		}
	}
	if keyFile != "" {
		keyPEM, err := ioutil.ReadFile(keyFile)
		if err != nil {
			log.Fatalf("Error: %v", err)
		} else {
			priv, err = helpers.ParsePrivateKeyPEM(keyPEM)
		}
	}
	if err != nil {
		log.Fatalf("Error: %v", err)
	}

	// Load response file
	if responseFile != "" {
		log.Printf("Loading response file: %v", responseFile)
		response, err = ioutil.ReadFile(responseFile)
		if err != nil {
			log.Fatalf("Error: %v", err)
		}
	} else {
		response = []byte("Welcome to the TLS 1.3 zone!")
	}

	config := mint.Config{
		SendSessionTickets: true,
		ServerName:         serverName,
	}

	if certChain != nil && priv != nil {
		log.Printf("Loading cert: %v key: %v", certFile, keyFile)
		config.Certificates = []*mint.Certificate{
			&mint.Certificate{
				Chain:      certChain,
				PrivateKey: priv,
			},
		}
	}
	config.Init(false)

	service := "0.0.0.0:" + port
	listener, err := mint.Listen("tcp", service, &config)

	if err != nil {
		log.Printf("Error: %v", err)
	}

	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		w.Write(response)
	})

	s := &http.Server{}
	s.Serve(listener)
}
<|endoftext|>


<commit_before>/*
Copyright 2019 The Knative Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package testing

import (
	"context"
	"testing"
	"time"

	"go.uber.org/atomic"

	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/runtime/schema"
	"k8s.io/apimachinery/pkg/runtime/serializer"
	"k8s.io/apimachinery/pkg/util/wait"
	"k8s.io/apimachinery/pkg/watch"
	"k8s.io/client-go/rest"
	clientgotesting "k8s.io/client-go/testing"
	"k8s.io/client-go/tools/record"

	"knative.dev/pkg/controller"
	"knative.dev/pkg/injection"
	logtesting "knative.dev/pkg/logging/testing"
)

// SetupFakeContext sets up the the Context and the fake informers for the tests.
func SetupFakeContext(t testing.TB) (context.Context, []controller.Informer) {
	c, _, is := SetupFakeContextWithCancel(t)
	return c, is
}

// SetupFakeContextWithCancel sets up the the Context and the fake informers for the tests
// The provided context can be canceled using provided callback.
func SetupFakeContextWithCancel(t testing.TB) (context.Context, context.CancelFunc, []controller.Informer) {
	ctx, c := context.WithCancel(logtesting.TestContextWithLogger(t))
	ctx = controller.WithEventRecorder(ctx, record.NewFakeRecorder(1000))
	ctx, is := injection.Fake.SetupInformers(ctx, &rest.Config{})
	return ctx, c, is
}

// fakeClient is an interface capturing the two functions we need from fake clients.
type fakeClient interface {
	PrependWatchReactor(resource string, reaction clientgotesting.WatchReactionFunc)
	PrependReactor(verb, resource string, reaction clientgotesting.ReactionFunc)
}

// withTracker is an interface capturing only the Tracker function. The dynamic client
// currently does not have that, so we need to special-case it.
type withTracker interface {
	Tracker() clientgotesting.ObjectTracker
}

// RunAndSyncInformers runs the given informers, then makes sure their caches are all
// synced and in addition makes sure that all the Watch calls have been properly setup.
// See https://github.com/kubernetes/kubernetes/issues/95372 for background on the Watch
// calls tragedy.
func RunAndSyncInformers(ctx context.Context, informers ...controller.Informer) (func(), error) {
	var watchesPending atomic.Int32

	for _, client := range injection.Fake.FetchAllClients(ctx) {
		c := client.(fakeClient)

		var tracker clientgotesting.ObjectTracker
		if withTracker, ok := c.(withTracker); ok {
			tracker = withTracker.Tracker()
		} else {
			// Required setup for the dynamic client as it doesn't define a Tracker() function.
			// TODO(markusthoemmes): Drop this if https://github.com/kubernetes/kubernetes/pull/100085 lands.
			scheme := runtime.NewScheme()
			scheme.AddKnownTypeWithName(schema.GroupVersionKind{Group: "fake-dynamic-client-group", Version: "v1", Kind: "List"}, &unstructured.UnstructuredList{})
			codecs := serializer.NewCodecFactory(scheme)
			tracker = clientgotesting.NewObjectTracker(scheme, codecs.UniversalDecoder())
		}

		c.PrependReactor("list", "*", func(action clientgotesting.Action) (handled bool, ret runtime.Object, err error) {
			// Every list (before actual informer usage) is going to be followed by a Watch call.
			watchesPending.Inc()
			return false, nil, nil
		})

		c.PrependWatchReactor("*", func(action clientgotesting.Action) (handled bool, ret watch.Interface, err error) {
			// The actual Watch call. This is a reimplementation of the default Watch
			// calls in fakes to guarantee we have actually **done** the work.
			gvr := action.GetResource()
			ns := action.GetNamespace()
			watch, err := tracker.Watch(gvr, ns)
			if err != nil {
				return false, nil, err
			}

			watchesPending.Dec()

			return true, watch, nil
		})
	}

	wf, err := controller.RunInformers(ctx.Done(), informers...)
	if err != nil {
		return wf, err
	}

	err = wait.PollImmediate(time.Microsecond, wait.ForeverTestTimeout, func() (bool, error) {
		if watchesPending.Load() == 0 {
			return true, nil
		}
		return false, nil
	})
	return wf, err
}
<commit_msg>add optional fs() to edit fake ctx for testing purpose (#2057)<commit_after>/*
Copyright 2019 The Knative Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package testing

import (
	"context"
	"testing"
	"time"

	"go.uber.org/atomic"

	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/runtime/schema"
	"k8s.io/apimachinery/pkg/runtime/serializer"
	"k8s.io/apimachinery/pkg/util/wait"
	"k8s.io/apimachinery/pkg/watch"
	"k8s.io/client-go/rest"
	clientgotesting "k8s.io/client-go/testing"
	"k8s.io/client-go/tools/record"

	"knative.dev/pkg/controller"
	"knative.dev/pkg/injection"
	logtesting "knative.dev/pkg/logging/testing"
)

// SetupFakeContext sets up the the Context and the fake informers for the tests.
// The optional fs() can be used to edit ctx before the SetupInformer steps
func SetupFakeContext(t testing.TB, fs ...func(context.Context) context.Context) (context.Context, []controller.Informer) {
	c, _, is := SetupFakeContextWithCancel(t, fs...)
	return c, is
}

// SetupFakeContextWithCancel sets up the the Context and the fake informers for the tests
// The provided context can be canceled using provided callback.
// The optional fs() can be used to edit ctx before the SetupInformer steps
func SetupFakeContextWithCancel(t testing.TB, fs ...func(context.Context) context.Context) (context.Context, context.CancelFunc, []controller.Informer) {
	ctx, c := context.WithCancel(logtesting.TestContextWithLogger(t))
	ctx = controller.WithEventRecorder(ctx, record.NewFakeRecorder(1000))
	for _, f := range fs {
		ctx = f(ctx)
	}
	ctx, is := injection.Fake.SetupInformers(ctx, &rest.Config{})
	return ctx, c, is
}

// fakeClient is an interface capturing the two functions we need from fake clients.
type fakeClient interface {
	PrependWatchReactor(resource string, reaction clientgotesting.WatchReactionFunc)
	PrependReactor(verb, resource string, reaction clientgotesting.ReactionFunc)
}

// withTracker is an interface capturing only the Tracker function. The dynamic client
// currently does not have that, so we need to special-case it.
type withTracker interface {
	Tracker() clientgotesting.ObjectTracker
}

// RunAndSyncInformers runs the given informers, then makes sure their caches are all
// synced and in addition makes sure that all the Watch calls have been properly setup.
// See https://github.com/kubernetes/kubernetes/issues/95372 for background on the Watch
// calls tragedy.
func RunAndSyncInformers(ctx context.Context, informers ...controller.Informer) (func(), error) {
	var watchesPending atomic.Int32

	for _, client := range injection.Fake.FetchAllClients(ctx) {
		c := client.(fakeClient)

		var tracker clientgotesting.ObjectTracker
		if withTracker, ok := c.(withTracker); ok {
			tracker = withTracker.Tracker()
		} else {
			// Required setup for the dynamic client as it doesn't define a Tracker() function.
			// TODO(markusthoemmes): Drop this if https://github.com/kubernetes/kubernetes/pull/100085 lands.
			scheme := runtime.NewScheme()
			scheme.AddKnownTypeWithName(schema.GroupVersionKind{Group: "fake-dynamic-client-group", Version: "v1", Kind: "List"}, &unstructured.UnstructuredList{})
			codecs := serializer.NewCodecFactory(scheme)
			tracker = clientgotesting.NewObjectTracker(scheme, codecs.UniversalDecoder())
		}

		c.PrependReactor("list", "*", func(action clientgotesting.Action) (handled bool, ret runtime.Object, err error) {
			// Every list (before actual informer usage) is going to be followed by a Watch call.
			watchesPending.Inc()
			return false, nil, nil
		})

		c.PrependWatchReactor("*", func(action clientgotesting.Action) (handled bool, ret watch.Interface, err error) {
			// The actual Watch call. This is a reimplementation of the default Watch
			// calls in fakes to guarantee we have actually **done** the work.
			gvr := action.GetResource()
			ns := action.GetNamespace()
			watch, err := tracker.Watch(gvr, ns)
			if err != nil {
				return false, nil, err
			}

			watchesPending.Dec()

			return true, watch, nil
		})
	}

	wf, err := controller.RunInformers(ctx.Done(), informers...)
	if err != nil {
		return wf, err
	}

	err = wait.PollImmediate(time.Microsecond, wait.ForeverTestTimeout, func() (bool, error) {
		if watchesPending.Load() == 0 {
			return true, nil
		}
		return false, nil
	})
	return wf, err
}
<|endoftext|>


<commit_before>package ui  // import "miniflux.app/ui"

import (
	"net/http"

	"miniflux.app/http/context"
	"miniflux.app/http/cookie"
	"miniflux.app/http/request"
	"miniflux.app/http/response"
	"miniflux.app/http/response/html"
	"miniflux.app/http/route"
	"miniflux.app/logger"
	"miniflux.app/ui/form"
	"miniflux.app/ui/session"
	"miniflux.app/ui/view"
)

// CheckLogin validates the username/password and redirects the user to the unread page.
func (c *Controller) CheckLogin(w http.ResponseWriter, r *http.Request) {
	ctx := context.New(r)
	sess := session.New(c.store, ctx)

	authForm := form.NewAuthForm(r)

	view := view.New(c.tpl, ctx, sess)
	view.Set("errorMessage", "Invalid username or password.")
	view.Set("form", authForm)

	if err := authForm.Validate(); err != nil {
		logger.Error("[Controller:CheckLogin] %v", err)
		html.OK(w, r, view.Render("login"))
		return
	}

	if err := c.store.CheckPassword(authForm.Username, authForm.Password); err != nil {
		logger.Error("[Controller:CheckLogin] %v", err)
		html.OK(w, r, view.Render("login"))
		return
	}

	sessionToken, userID, err := c.store.CreateUserSession(authForm.Username, r.UserAgent(), request.RealIP(r))
	if err != nil {
		html.ServerError(w, err)
		return
	}

	logger.Info("[Controller:CheckLogin] username=%s just logged in", authForm.Username)
	c.store.SetLastLogin(userID)

	user, err := c.store.UserByID(userID)
	if err != nil {
		html.ServerError(w, err)
		return
	}

	sess.SetLanguage(user.Language)
	sess.SetTheme(user.Theme)

	http.SetCookie(w, cookie.New(
		cookie.CookieUserSessionID,
		sessionToken,
		c.cfg.IsHTTPS,
		c.cfg.BasePath(),
	))

	response.Redirect(w, r, route.Path(c.router, "unread"))
}
<commit_msg>Added remote client IP to login failure error message.<commit_after>package ui  // import "miniflux.app/ui"

import (
	"net/http"

	"miniflux.app/http/context"
	"miniflux.app/http/cookie"
	"miniflux.app/http/request"
	"miniflux.app/http/response"
	"miniflux.app/http/response/html"
	"miniflux.app/http/route"
	"miniflux.app/logger"
	"miniflux.app/ui/form"
	"miniflux.app/ui/session"
	"miniflux.app/ui/view"
)

// CheckLogin validates the username/password and redirects the user to the unread page.
func (c *Controller) CheckLogin(w http.ResponseWriter, r *http.Request) {
	remoteAddr := request.RealIP(r)

	ctx := context.New(r)
	sess := session.New(c.store, ctx)

	authForm := form.NewAuthForm(r)

	view := view.New(c.tpl, ctx, sess)
	view.Set("errorMessage", "Invalid username or password.")
	view.Set("form", authForm)

	if err := authForm.Validate(); err != nil {
		logger.Error("[Controller:CheckLogin] %v", err)
		html.OK(w, r, view.Render("login"))
		return
	}

	if err := c.store.CheckPassword(authForm.Username, authForm.Password); err != nil {
		logger.Error("[Controller:CheckLogin] [Remote=%v] %v", remoteAddr, err)
		html.OK(w, r, view.Render("login"))
		return
	}

	sessionToken, userID, err := c.store.CreateUserSession(authForm.Username, r.UserAgent(), remoteAddr)
	if err != nil {
		html.ServerError(w, err)
		return
	}

	logger.Info("[Controller:CheckLogin] username=%s just logged in", authForm.Username)
	c.store.SetLastLogin(userID)

	user, err := c.store.UserByID(userID)
	if err != nil {
		html.ServerError(w, err)
		return
	}

	sess.SetLanguage(user.Language)
	sess.SetTheme(user.Theme)

	http.SetCookie(w, cookie.New(
		cookie.CookieUserSessionID,
		sessionToken,
		c.cfg.IsHTTPS,
		c.cfg.BasePath(),
	))

	response.Redirect(w, r, route.Path(c.router, "unread"))
}
<|endoftext|>


<commit_before>package signals

import (
	"fmt"
	"math"
	"time"
)

// function types can represent an analogue y as it varies with x
type Function interface {
	call(x) y
}

// returns a PeriodicLimitedFunction (type multiplex) based on a sine wave,
// with peak y set to Maxy adjusted by dB,
// so dB should always be negative.
func NewTone(period x, dB float64) Modulated {
	return Modulated{Sine{period}, NewConstant(dB)}
}

// x represents a value from -infinity to +infinity, but is actually limited by its current underlying representation.
// -ve x's are considered imaginary, not used, unless a Delay makes them +ve.
type x time.Duration // current underlying representation

func (i x) String() string {
	return fmt.Sprintf("%9.2f", float32(i)/float32(unitX))
}

// use time.Second as sensible middle of resolution range of time.Duration.
const unitX = x(time.Second)

// the y type represents a value between +maxY and -maxY.
type y int64

const maxY y = math.MaxInt64
const yBits = 64
const halfyBits = yBits / 2

//const Halfy=2<<(HalfyBits-1)

// float64 has less resolution than int64 at maxy, so need this to scale float64 sourced functions to never overflow int64
const maxyfloat64 float64 = float64(maxY - 512)

func (l y) String() string {
	return fmt.Sprintf("%9.2f%%", 100*float32(l)/float32(maxY))
}

// peaker adds a PeakY method requirement.
type peaker interface {
	PeakY() y
}

// LimitedFunctions are used as Functions that can be assumed is zero after MaxX
type LimitedFunction interface {
	Function
	MaxX() x
}

// Samples are LimitedFunctions that can be assumed to be zero before their MinX.
type Sample interface {
	LimitedFunction
	MinX() x
}

// PeriodicalFunctions are functions that can be assumed to repeat over Period().
type PeriodicFunction interface {
	Function
	Period() x
}

// LimitedPeriodicalFunction are Functions that repeat over Period() and dont exceed MaxY().
type PeriodicLimitedFunction interface {
	LimitedFunction
	Period() x
}

// PeakingLimitedFunctions are Functions that can be assumed is zero after a MaxX() and dont exceed a MaxY().
type PeakingLimitedFunction interface {
	LimitedFunction
	peaker
}

// PeakingLimitedPeriodicalFunction are Functions that can be assumed is zero after a MaxX(), repeat over Period() and dont exceed MaxY().
type PeakingPeriodicLimitedFunction interface {
	LimitedFunction
	Period() x
	peaker
}

// Converters to promote slices of interfaces, needed when using variadic parameters called using a slice since go doesn't automatically promote a narrow interface inside the slice to be able to use a broader interface.
// for example: without these you couldn't use a slice of LimitedFunction's in a variadic call to a func requiring Function's. (when you can use separate LimitedFunction's in the same call.)

// converts []LimitedFunction to []Function
func PromoteSliceLimitedFunctionsToFunctions(s []LimitedFunction) []Function {
	out := make([]Function, len(s))
	for i := range out {
		out[i] = s[i].(Function)
	}
	return out
}

// converts []PeriodicLimitedFunction to []Function
func PromoteSlicePeriodicLimitedFunctionsToFunctions(s []PeriodicLimitedFunction) []Function {
	out := make([]Function, len(s))
	for i := range out {
		out[i] = s[i].(Function)
	}
	return out
}

// converts []PeriodicFunction to []Function
func PromoteSlicePeriodicFunctionsToFunctions(s []PeriodicFunction) []Function {
	out := make([]Function, len(s))
	for i := range out {
		out[i] = s[i].(Function)
	}
	return out
}

// converts []PeriodicLimitedFunction to []LimitedFunction
func PromoteSlicePeriodicLimitedFunctionsToLimitedFunctions(s []PeriodicLimitedFunction) []LimitedFunction {
	out := make([]LimitedFunction, len(s))
	for i := range out {
		out[i] = s[i].(LimitedFunction)
	}
	return out
}

// converts []PCMFunction to []Function
func PromoteSlicePCMFunctionsToFunctions(s []PCMFunction) []Function {
	out := make([]Function, len(s))
	for i := range out {
		out[i] = s[i].(Function)
	}
	return out
}

// converts []PCMFunction to []LimitedFunction
func PromoteSlicePCMFunctionsToLimitedFunctions(s []PCMFunction) []LimitedFunction {
	out := make([]LimitedFunction, len(s))
	for i := range out {
		out[i] = s[i].(LimitedFunction)
	}
	return out
}

// converts []PCMFunction to []PeriodicLimitedFunction
func PromoteSlicePCMFunctionsToPeriodicLimitedFunctions(s []PCMFunction) []PeriodicLimitedFunction {
	out := make([]PeriodicLimitedFunction, len(s))
	for i := range out {
		out[i] = s[i].(PeriodicLimitedFunction)
	}
	return out
}

// converts []PCMFunction to []PeriodicFunction
func PromoteSlicePCMFunctionsToPeriodicFunctions(s []PCMFunction) []PeriodicFunction {
	out := make([]PeriodicFunction, len(s))
	for i := range out {
		out[i] = s[i].(PeriodicFunction)
	}
	return out
}
<commit_msg>comments<commit_after>package signals

import (
	"fmt"
	"math"
	"time"
)

// function types can represent an analogue y as it varies with x
type Function interface {
	call(x) y
}

// returns a PeriodicLimitedFunction (type multiplex) based on a sine wave,
// with peak y set to Maxy adjusted by dB,
// so dB should always be negative.
func NewTone(period x, dB float64) Modulated {
	return Modulated{Sine{period}, NewConstant(dB)}
}

// the x represents a value from -infinity to +infinity, but is actually limited by its current underlying representation.
// -ve x's are considered imaginary, not used, unless a Delay makes them +ve.
type x time.Duration // current underlying representation

func (i x) String() string {
	return fmt.Sprintf("%9.2f", float32(i)/float32(unitX))
}

// somewhere close to the middle of the resolution range.
const unitX = x(time.Second)

// the y type represents a value between +maxY and -maxY.
type y int64

const maxY y = math.MaxInt64
const yBits = 64
const halfyBits = yBits / 2

//const Halfy=2<<(HalfyBits-1)

// float64 has less resolution than int64 at maxy, so need this to scale float64 sourced functions to never overflow int64
const maxyfloat64 float64 = float64(maxY - 512)

func (l y) String() string {
	return fmt.Sprintf("%9.2f%%", 100*float32(l)/float32(maxY))
}

// peaker adds a PeakY method requirement.
type peaker interface {
	PeakY() y
}

// LimitedFunctions are used as Functions that can be assumed is zero after MaxX
type LimitedFunction interface {
	Function
	MaxX() x
}

// Samples are LimitedFunctions that are assumed to be zero before their MinX.
type Sample interface {
	LimitedFunction
	MinX() x
}

// PeriodicalFunctions are functions that can be assumed to repeat over Period().
type PeriodicFunction interface {
	Function
	Period() x
}

// LimitedPeriodicalFunction are Functions that repeat over Period() and dont exceed MaxY().
type PeriodicLimitedFunction interface {
	LimitedFunction
	Period() x
}

// PeakingLimitedFunctions are Functions that can be assumed is zero after a MaxX() and dont exceed a MaxY().
type PeakingLimitedFunction interface {
	LimitedFunction
	peaker
}

// PeakingLimitedPeriodicalFunction are Functions that can be assumed is zero after a MaxX(), repeat over Period() and dont exceed MaxY().
type PeakingPeriodicLimitedFunction interface {
	LimitedFunction
	Period() x
	peaker
}

// Converters to promote slices of interfaces, needed when using variadic parameters called using a slice since go doesn't automatically promote a narrow interface inside the slice to be able to use a broader interface.
// for example: without these you couldn't use a slice of LimitedFunction's in a variadic call to a func requiring Function's. (when you can use separate LimitedFunction's in the same call.)

// converts []LimitedFunction to []Function
func PromoteSliceLimitedFunctionsToFunctions(s []LimitedFunction) []Function {
	out := make([]Function, len(s))
	for i := range out {
		out[i] = s[i].(Function)
	}
	return out
}

// converts []PeriodicLimitedFunction to []Function
func PromoteSlicePeriodicLimitedFunctionsToFunctions(s []PeriodicLimitedFunction) []Function {
	out := make([]Function, len(s))
	for i := range out {
		out[i] = s[i].(Function)
	}
	return out
}

// converts []PeriodicFunction to []Function
func PromoteSlicePeriodicFunctionsToFunctions(s []PeriodicFunction) []Function {
	out := make([]Function, len(s))
	for i := range out {
		out[i] = s[i].(Function)
	}
	return out
}

// converts []PeriodicLimitedFunction to []LimitedFunction
func PromoteSlicePeriodicLimitedFunctionsToLimitedFunctions(s []PeriodicLimitedFunction) []LimitedFunction {
	out := make([]LimitedFunction, len(s))
	for i := range out {
		out[i] = s[i].(LimitedFunction)
	}
	return out
}

// converts []PCMFunction to []Function
func PromoteSlicePCMFunctionsToFunctions(s []PCMFunction) []Function {
	out := make([]Function, len(s))
	for i := range out {
		out[i] = s[i].(Function)
	}
	return out
}

// converts []PCMFunction to []LimitedFunction
func PromoteSlicePCMFunctionsToLimitedFunctions(s []PCMFunction) []LimitedFunction {
	out := make([]LimitedFunction, len(s))
	for i := range out {
		out[i] = s[i].(LimitedFunction)
	}
	return out
}

// converts []PCMFunction to []PeriodicLimitedFunction
func PromoteSlicePCMFunctionsToPeriodicLimitedFunctions(s []PCMFunction) []PeriodicLimitedFunction {
	out := make([]PeriodicLimitedFunction, len(s))
	for i := range out {
		out[i] = s[i].(PeriodicLimitedFunction)
	}
	return out
}

// converts []PCMFunction to []PeriodicFunction
func PromoteSlicePCMFunctionsToPeriodicFunctions(s []PCMFunction) []PeriodicFunction {
	out := make([]PeriodicFunction, len(s))
	for i := range out {
		out[i] = s[i].(PeriodicFunction)
	}
	return out
}
<|endoftext|>


<commit_before>package app

import (
	"encoding/json"
	"fmt"
	"net/http"
	"reflect"
	"strconv"
	"time"

	"gopkg.in/olivere/elastic.v3"

	"github.com/labstack/echo"
	"github.com/topfreegames/mqttbot/es"
	"github.com/topfreegames/mqttbot/logger"
)

type Message struct {
	Timestamp time.Time `json:"timestamp"`
	Payload   string    `json:"payload"`
	Topic     string    `json:"topic"`
}

// HistoryHandler is the handler responsible for sending the rooms history to the player
func HistoryHandler(app *App) func(c echo.Context) error {
	return func(c echo.Context) error {
		esclient := es.GetESClient()
		c.Set("route", "History")
		topic := c.ParamValues()[0]
		userId := c.QueryParam("userid")
		from, err := strconv.Atoi(c.QueryParam("from"))
		limit, err := strconv.Atoi(c.QueryParam("limit"))

		if limit == 0 {
			limit = 10
		}

		logger.Logger.Debugf("user %s is asking for history for topic %s with args from=%d and limit=%d", userId, topic, from, limit)
		rc := app.RedisClient.Pool.Get()
		defer rc.Close()
		rc.Send("MULTI")
		rc.Send("GET", userId)
		rc.Send("GET", fmt.Sprintf("%s-%s", userId, topic))
		r, err := rc.Do("EXEC")
		if err != nil {
			return err
		}
		redisResults := (r.([]interface{}))
		if redisResults[0] != nil && redisResults[1] != nil {
			termQuery := elastic.NewQueryStringQuery(fmt.Sprintf("topic:\"%s\"", topic))
			searchResults, err := esclient.Search().Index("chat").Query(termQuery).
				Sort("timestamp", false).From(from).Size(limit).Do()
			if err != nil {
				return err
			}
			messages := []Message{}
			var ttyp Message
			for _, item := range searchResults.Each(reflect.TypeOf(ttyp)) {
				if t, ok := item.(Message); ok {
					messages = append(messages, t)
				}
			}
			jsonMessages, _ := json.Marshal(messages)
			return c.JSON(http.StatusOK, jsonMessages)
		} else {
			return c.String(echo.ErrUnauthorized.Code, echo.ErrUnauthorized.Message)
		}
	}
}
<commit_msg>fix bug in returning history<commit_after>package app

import (
	"fmt"
	"net/http"
	"reflect"
	"strconv"
	"time"

	"gopkg.in/olivere/elastic.v3"

	"github.com/labstack/echo"
	"github.com/topfreegames/mqttbot/es"
	"github.com/topfreegames/mqttbot/logger"
)

type Message struct {
	Timestamp time.Time `json:"timestamp"`
	Payload   string    `json:"payload"`
	Topic     string    `json:"topic"`
}

// HistoryHandler is the handler responsible for sending the rooms history to the player
func HistoryHandler(app *App) func(c echo.Context) error {
	return func(c echo.Context) error {
		esclient := es.GetESClient()
		c.Set("route", "History")
		topic := c.ParamValues()[0]
		userId := c.QueryParam("userid")
		from, err := strconv.Atoi(c.QueryParam("from"))
		limit, err := strconv.Atoi(c.QueryParam("limit"))

		if limit == 0 {
			limit = 10
		}

		logger.Logger.Debugf("user %s is asking for history for topic %s with args from=%d and limit=%d", userId, topic, from, limit)
		rc := app.RedisClient.Pool.Get()
		defer rc.Close()
		rc.Send("MULTI")
		rc.Send("GET", userId)
		rc.Send("GET", fmt.Sprintf("%s-%s", userId, topic))
		r, err := rc.Do("EXEC")
		if err != nil {
			return err
		}
		redisResults := (r.([]interface{}))
		if redisResults[0] != nil && redisResults[1] != nil {
			termQuery := elastic.NewQueryStringQuery(fmt.Sprintf("topic:\"%s\"", topic))
			searchResults, err := esclient.Search().Index("chat").Query(termQuery).
				Sort("timestamp", false).From(from).Size(limit).Do()
			if err != nil {
				return err
			}
			messages := []Message{}
			var ttyp Message
			for _, item := range searchResults.Each(reflect.TypeOf(ttyp)) {
				if t, ok := item.(Message); ok {
					messages = append(messages, t)
				}
			}
			return c.JSON(http.StatusOK, messages)
		} else {
			return c.String(echo.ErrUnauthorized.Code, echo.ErrUnauthorized.Message)
		}
	}
}
<|endoftext|>