<commit_before>package main

import (
	"bufio"
	"fmt"
	"os"
	"os/signal"
	"strings"
	"syscall"

	log "github.com/Sirupsen/logrus"
	"github.com/smancke/guble/client"
	"github.com/smancke/guble/protocol"
	"gopkg.in/alecthomas/kingpin.v2"
)

var (
	exit     = kingpin.Flag("exit", "Exit after sending the commands").Short('x').Bool()
	commands = kingpin.Arg("commands", "The commands to send after startup").Strings()
	verbose  = kingpin.Flag("verbose", "Display verbose server communication").Short('v').Bool()
	url      = kingpin.Flag("url", "The websocket url to connect to").Default("ws://localhost:8080/stream/").String()
	user     = kingpin.Flag("user", "The user name to connect with (guble-cli)").Short('u').Default("guble-cli").String()
	logLevel = kingpin.Flag("log", "Log level").
			Short('l').
			Default(log.ErrorLevel.String()).
			Envar("GUBLE_LOG").
			Enum(logLevels()...)

	logger = log.WithField("app", "guble-cli")
)

func logLevels() (levels []string) {
	for _, level := range log.AllLevels {
		levels = append(levels, level.String())
	}
	return
}

// This is a minimal commandline client to connect through a websocket
func main() {
	kingpin.Parse()

	// set log level
	level, err := log.ParseLevel(*logLevel)
	if err != nil {
		logger.WithField("error", err).Fatal("Invalid log level")
	}
	log.SetLevel(level)

	origin := "http://localhost/"
	url := fmt.Sprintf("%v/user/%v", removeTrailingSlash(*url), *user)
	client, err := client.Open(url, origin, 100, true)
	if err != nil {
		log.Fatal(err)
	}

	go writeLoop(client)
	go readLoop(client)

	for _, cmd := range *commands {
		client.WriteRawMessage([]byte(cmd))
	}
	if *exit {
		return
	}
	waitForTermination(func() {})
}

func readLoop(client client.Client) {
	for {
		select {
		case incomingMessage := <-client.Messages():
			if *verbose {
				fmt.Println(string(incomingMessage.Bytes()))
			} else {
				fmt.Printf("%v: %v\n", incomingMessage.UserID, incomingMessage.BodyAsString())
			}
		case e := <-client.Errors():
			fmt.Println("ERROR: " + string(e.Bytes()))
		case status := <-client.StatusMessages():
			fmt.Println(string(status.Bytes()))
			fmt.Println()
		}
	}
}

func writeLoop(client client.Client) {
	shouldStop := false
	for !shouldStop {
		func() {
			defer protocol.PanicLogger()
			reader := bufio.NewReader(os.Stdin)
			text, _ := reader.ReadString('\n')
			if strings.TrimSpace(text) == "" {
				return
			}

			if strings.TrimSpace(text) == "?" || strings.TrimSpace(text) == "help" {
				printHelp()
				return
			}

			if strings.HasPrefix(text, ">") {
				fmt.Print("header: ")
				header, _ := reader.ReadString('\n')
				text += header
				fmt.Print("body: ")
				body, _ := reader.ReadString('\n')
				text += strings.TrimSpace(body)
			}

			if *verbose {
				log.Printf("Sending: %v\n", text)
			}
			if err := client.WriteRawMessage([]byte(text)); err != nil {
				shouldStop = true
				logger.WithError(err).Error("Error on Writing  message")
			}
		}()
	}
}

func waitForTermination(callback func()) {
	sigc := make(chan os.Signal)
	signal.Notify(sigc, syscall.SIGINT, syscall.SIGTERM)
	log.Printf("%q", <-sigc)
	callback()
	os.Exit(0)
}

func printHelp() {
	fmt.Println(`
## Commands
?           # print this info

+ /foo/bar  # subscribe to the topic /foo/bar
+ /foo 0    # read from message 0 and subscribe to the topic /foo
+ /foo 0 5  # read messages 0-5 from /foo
+ /foo -5   # read the last 5 messages and subscribe to the topic /foo

- /foo      # cancel the subscription for /foo

> /foo         # send a message to /foo
> /foo/bar 42  # send a message to /foo/bar with publisherid 42
`)
}

func removeTrailingSlash(path string) string {
	if len(path) > 1 && path[len(path)-1] == '/' {
		return path[:len(path)-1]
	}
	return path
}
<commit_msg>error-checking in cli<commit_after>package main

import (
	"bufio"
	"fmt"
	"os"
	"os/signal"
	"strings"
	"syscall"

	log "github.com/Sirupsen/logrus"
	"github.com/smancke/guble/client"
	"github.com/smancke/guble/protocol"
	"gopkg.in/alecthomas/kingpin.v2"
)

var (
	exit     = kingpin.Flag("exit", "Exit after sending the commands").Short('x').Bool()
	commands = kingpin.Arg("commands", "The commands to send after startup").Strings()
	verbose  = kingpin.Flag("verbose", "Display verbose server communication").Short('v').Bool()
	url      = kingpin.Flag("url", "The websocket url to connect to").Default("ws://localhost:8080/stream/").String()
	user     = kingpin.Flag("user", "The user name to connect with (guble-cli)").Short('u').Default("guble-cli").String()
	logLevel = kingpin.Flag("log", "Log level").
			Short('l').
			Default(log.ErrorLevel.String()).
			Envar("GUBLE_LOG").
			Enum(logLevels()...)

	logger = log.WithField("app", "guble-cli")
)

func logLevels() (levels []string) {
	for _, level := range log.AllLevels {
		levels = append(levels, level.String())
	}
	return
}

// This is a minimal commandline client to connect through a websocket
func main() {
	kingpin.Parse()

	// set log level
	level, err := log.ParseLevel(*logLevel)
	if err != nil {
		logger.WithField("error", err).Fatal("Invalid log level")
	}
	log.SetLevel(level)

	origin := "http://localhost/"
	url := fmt.Sprintf("%v/user/%v", removeTrailingSlash(*url), *user)
	client, err := client.Open(url, origin, 100, true)
	if err != nil {
		log.Fatal(err)
	}

	go writeLoop(client)
	go readLoop(client)

	for _, cmd := range *commands {
		client.WriteRawMessage([]byte(cmd))
	}
	if *exit {
		return
	}
	waitForTermination(func() {})
}

func readLoop(client client.Client) {
	for {
		select {
		case incomingMessage := <-client.Messages():
			if *verbose {
				fmt.Println(string(incomingMessage.Bytes()))
			} else {
				fmt.Printf("%v: %v\n", incomingMessage.UserID, incomingMessage.BodyAsString())
			}
		case e := <-client.Errors():
			fmt.Println("ERROR: " + string(e.Bytes()))
		case status := <-client.StatusMessages():
			fmt.Println(string(status.Bytes()))
			fmt.Println()
		}
	}
}

func writeLoop(client client.Client) {
	shouldStop := false
	for !shouldStop {
		func() {
			defer protocol.PanicLogger()
			reader := bufio.NewReader(os.Stdin)
			text, err := reader.ReadString('\n')
			if err != nil {
				return
			}
			if strings.TrimSpace(text) == "" {
				return
			}

			if strings.TrimSpace(text) == "?" || strings.TrimSpace(text) == "help" {
				printHelp()
				return
			}

			if strings.HasPrefix(text, ">") {
				fmt.Print("header: ")
				header, err := reader.ReadString('\n')
				if err != nil {
					return
				}
				text += header
				fmt.Print("body: ")
				body, err := reader.ReadString('\n')
				if err != nil {
					return
				}
				text += strings.TrimSpace(body)
			}

			if *verbose {
				log.Printf("Sending: %v\n", text)
			}
			if err := client.WriteRawMessage([]byte(text)); err != nil {
				shouldStop = true
				logger.WithError(err).Error("Error on Writing  message")
			}
		}()
	}
}

func waitForTermination(callback func()) {
	sigc := make(chan os.Signal)
	signal.Notify(sigc, syscall.SIGINT, syscall.SIGTERM)
	log.Printf("%q", <-sigc)
	callback()
	os.Exit(0)
}

func printHelp() {
	fmt.Println(`
## Commands
?           # print this info

+ /foo/bar  # subscribe to the topic /foo/bar
+ /foo 0    # read from message 0 and subscribe to the topic /foo
+ /foo 0 5  # read messages 0-5 from /foo
+ /foo -5   # read the last 5 messages and subscribe to the topic /foo

- /foo      # cancel the subscription for /foo

> /foo         # send a message to /foo
> /foo/bar 42  # send a message to /foo/bar with publisherid 42
`)
}

func removeTrailingSlash(path string) string {
	if len(path) > 1 && path[len(path)-1] == '/' {
		return path[:len(path)-1]
	}
	return path
}
<|endoftext|>


<commit_before><commit_msg>Add log message on import<commit_after><|endoftext|>


<commit_before>package ethminer

import (
	"bytes"
	"sort"

	"github.com/ethereum/eth-go/ethchain"
	"github.com/ethereum/eth-go/ethlog"
	"github.com/ethereum/eth-go/ethreact"
	"github.com/ethereum/eth-go/ethwire"
)

var logger = ethlog.NewLogger("MINER")

type Miner struct {
	pow         ethchain.PoW
	ethereum    ethchain.EthManager
	coinbase    []byte
	reactChan   chan ethreact.Event
	txs         ethchain.Transactions
	uncles      []*ethchain.Block
	block       *ethchain.Block
	powChan     chan []byte
	powQuitChan chan ethreact.Event
	quitChan    chan chan error

	turbo bool
}

func (self *Miner) GetPow() ethchain.PoW {
	return self.pow
}

func NewDefaultMiner(coinbase []byte, ethereum ethchain.EthManager) *Miner {
	miner := Miner{
		pow:      &ethchain.EasyPow{},
		ethereum: ethereum,
		coinbase: coinbase,
	}

	return &miner
}

func (self *Miner) ToggleTurbo() {
	self.turbo = !self.turbo

	self.pow.Turbo(self.turbo)
}

func (miner *Miner) Start() {
	miner.reactChan = make(chan ethreact.Event, 1)   // This is the channel that receives 'updates' when ever a new transaction or block comes in
	miner.powChan = make(chan []byte, 1)             // This is the channel that receives valid sha hashes for a given block
	miner.powQuitChan = make(chan ethreact.Event, 1) // This is the channel that can exit the miner thread
	miner.quitChan = make(chan chan error, 1)

	// Insert initial TXs in our little miner 'pool'
	miner.txs = miner.ethereum.TxPool().Flush()
	miner.block = miner.ethereum.BlockChain().NewBlock(miner.coinbase)

	// Prepare inital block
	//miner.ethereum.StateManager().Prepare(miner.block.State(), miner.block.State())
	go miner.listener()

	reactor := miner.ethereum.Reactor()
	reactor.Subscribe("newBlock", miner.reactChan)
	reactor.Subscribe("newTx:pre", miner.reactChan)

	// We need the quit chan to be a Reactor event.
	// The POW search method is actually blocking and if we don't
	// listen to the reactor events inside of the pow itself
	// The miner overseer will never get the reactor events themselves
	// Only after the miner will find the sha
	reactor.Subscribe("newBlock", miner.powQuitChan)
	reactor.Subscribe("newTx:pre", miner.powQuitChan)

	logger.Infoln("Started")

	reactor.Post("miner:start", miner)
}

func (miner *Miner) listener() {
	for {
		select {
		case status := <-miner.quitChan:
			logger.Infoln("Stopped")
			status <- nil
			return
		case chanMessage := <-miner.reactChan:

			if block, ok := chanMessage.Resource.(*ethchain.Block); ok {
				//logger.Infoln("Got new block via Reactor")
				if bytes.Compare(miner.ethereum.BlockChain().CurrentBlock.Hash(), block.Hash()) == 0 {
					// TODO: Perhaps continue mining to get some uncle rewards
					//logger.Infoln("New top block found resetting state")

					// Filter out which Transactions we have that were not in this block
					var newtxs []*ethchain.Transaction
					for _, tx := range miner.txs {
						found := false
						for _, othertx := range block.Transactions() {
							if bytes.Compare(tx.Hash(), othertx.Hash()) == 0 {
								found = true
							}
						}
						if found == false {
							newtxs = append(newtxs, tx)
						}
					}
					miner.txs = newtxs

					// Setup a fresh state to mine on
					//miner.block = miner.ethereum.BlockChain().NewBlock(miner.coinbase, miner.txs)

				} else {
					if bytes.Compare(block.PrevHash, miner.ethereum.BlockChain().CurrentBlock.PrevHash) == 0 {
						logger.Infoln("Adding uncle block")
						miner.uncles = append(miner.uncles, block)
					}
				}
			}

			if tx, ok := chanMessage.Resource.(*ethchain.Transaction); ok {
				found := false
				for _, ctx := range miner.txs {
					if found = bytes.Compare(ctx.Hash(), tx.Hash()) == 0; found {
						break
					}

				}
				if found == false {
					// Undo all previous commits
					miner.block.Undo()
					// Apply new transactions
					miner.txs = append(miner.txs, tx)
				}
			}
		default:
			miner.mineNewBlock()
		}
	}
}

func (miner *Miner) Stop() {
	logger.Infoln("Stopping...")

	miner.powQuitChan <- ethreact.Event{}

	status := make(chan error)
	miner.quitChan <- status
	<-status

	reactor := miner.ethereum.Reactor()
	reactor.Unsubscribe("newBlock", miner.powQuitChan)
	reactor.Unsubscribe("newTx:pre", miner.powQuitChan)
	reactor.Unsubscribe("newBlock", miner.reactChan)
	reactor.Unsubscribe("newTx:pre", miner.reactChan)

	reactor.Post("miner:stop", miner)
}

func (self *Miner) mineNewBlock() {
	stateManager := self.ethereum.StateManager()

	self.block = self.ethereum.BlockChain().NewBlock(self.coinbase)

	// Apply uncles
	if len(self.uncles) > 0 {
		self.block.SetUncles(self.uncles)
	}

	// Sort the transactions by nonce in case of odd network propagation
	sort.Sort(ethchain.TxByNonce{self.txs})

	// Accumulate all valid transactions and apply them to the new state
	// Error may be ignored. It's not important during mining
	parent := self.ethereum.BlockChain().GetBlock(self.block.PrevHash)
	coinbase := self.block.State().GetOrNewStateObject(self.block.Coinbase)
	coinbase.SetGasPool(self.block.CalcGasLimit(parent))
	receipts, txs, unhandledTxs, err := stateManager.ProcessTransactions(coinbase, self.block.State(), self.block, self.block, self.txs)
	if err != nil {
		logger.Debugln(err)
	}
	self.txs = append(txs, unhandledTxs...)
	self.block.SetTxHash(receipts)

	// Set the transactions to the block so the new SHA3 can be calculated
	self.block.SetReceipts(receipts, txs)

	// Accumulate the rewards included for this block
	stateManager.AccumelateRewards(self.block.State(), self.block, parent)

	self.block.State().Update()

	logger.Infof("Mining on block. Includes %v transactions", len(self.txs))

	// Find a valid nonce
	self.block.Nonce = self.pow.Search(self.block, self.powQuitChan)
	if self.block.Nonce != nil {
		err := self.ethereum.StateManager().Process(self.block, false)
		if err != nil {
			logger.Infoln(err)
		} else {
			self.ethereum.Broadcast(ethwire.MsgBlockTy, []interface{}{self.block.Value().Val})
			logger.Infof("🔨  Mined block %x\n", self.block.Hash())
			logger.Infoln(self.block)
			// Gather the new batch of transactions currently in the tx pool
			self.txs = self.ethereum.TxPool().CurrentTransactions()
		}
	}
}
<commit_msg>don't mine without transactions<commit_after>package ethminer

import (
	"bytes"
	"sort"
	"time"

	"github.com/ethereum/eth-go/ethchain"
	"github.com/ethereum/eth-go/ethlog"
	"github.com/ethereum/eth-go/ethreact"
	"github.com/ethereum/eth-go/ethwire"
)

var logger = ethlog.NewLogger("MINER")

type Miner struct {
	pow         ethchain.PoW
	ethereum    ethchain.EthManager
	coinbase    []byte
	reactChan   chan ethreact.Event
	txs         ethchain.Transactions
	uncles      []*ethchain.Block
	block       *ethchain.Block
	powChan     chan []byte
	powQuitChan chan ethreact.Event
	quitChan    chan chan error

	turbo bool
}

func (self *Miner) GetPow() ethchain.PoW {
	return self.pow
}

func NewDefaultMiner(coinbase []byte, ethereum ethchain.EthManager) *Miner {
	miner := Miner{
		pow:      &ethchain.EasyPow{},
		ethereum: ethereum,
		coinbase: coinbase,
	}

	return &miner
}

func (self *Miner) ToggleTurbo() {
	self.turbo = !self.turbo

	self.pow.Turbo(self.turbo)
}

func (miner *Miner) Start() {
	miner.reactChan = make(chan ethreact.Event, 1)   // This is the channel that receives 'updates' when ever a new transaction or block comes in
	miner.powChan = make(chan []byte, 1)             // This is the channel that receives valid sha hashes for a given block
	miner.powQuitChan = make(chan ethreact.Event, 1) // This is the channel that can exit the miner thread
	miner.quitChan = make(chan chan error, 1)

	// Insert initial TXs in our little miner 'pool'
	miner.txs = miner.ethereum.TxPool().Flush()
	miner.block = miner.ethereum.BlockChain().NewBlock(miner.coinbase)

	// Prepare inital block
	//miner.ethereum.StateManager().Prepare(miner.block.State(), miner.block.State())
	go miner.listener()

	reactor := miner.ethereum.Reactor()
	reactor.Subscribe("newBlock", miner.reactChan)
	reactor.Subscribe("newTx:pre", miner.reactChan)

	// We need the quit chan to be a Reactor event.
	// The POW search method is actually blocking and if we don't
	// listen to the reactor events inside of the pow itself
	// The miner overseer will never get the reactor events themselves
	// Only after the miner will find the sha
	reactor.Subscribe("newBlock", miner.powQuitChan)
	reactor.Subscribe("newTx:pre", miner.powQuitChan)

	logger.Infoln("Started")

	reactor.Post("miner:start", miner)
}

func (miner *Miner) listener() {
	for {
		select {
		case status := <-miner.quitChan:
			logger.Infoln("Stopped")
			status <- nil
			return
		case chanMessage := <-miner.reactChan:

			if block, ok := chanMessage.Resource.(*ethchain.Block); ok {
				//logger.Infoln("Got new block via Reactor")
				if bytes.Compare(miner.ethereum.BlockChain().CurrentBlock.Hash(), block.Hash()) == 0 {
					// TODO: Perhaps continue mining to get some uncle rewards
					//logger.Infoln("New top block found resetting state")

					// Filter out which Transactions we have that were not in this block
					var newtxs []*ethchain.Transaction
					for _, tx := range miner.txs {
						found := false
						for _, othertx := range block.Transactions() {
							if bytes.Compare(tx.Hash(), othertx.Hash()) == 0 {
								found = true
							}
						}
						if found == false {
							newtxs = append(newtxs, tx)
						}
					}
					miner.txs = newtxs

					// Setup a fresh state to mine on
					//miner.block = miner.ethereum.BlockChain().NewBlock(miner.coinbase, miner.txs)

				} else {
					if bytes.Compare(block.PrevHash, miner.ethereum.BlockChain().CurrentBlock.PrevHash) == 0 {
						logger.Infoln("Adding uncle block")
						miner.uncles = append(miner.uncles, block)
					}
				}
			}

			if tx, ok := chanMessage.Resource.(*ethchain.Transaction); ok {
				found := false
				for _, ctx := range miner.txs {
					if found = bytes.Compare(ctx.Hash(), tx.Hash()) == 0; found {
						break
					}

				}
				if found == false {
					// Undo all previous commits
					miner.block.Undo()
					// Apply new transactions
					miner.txs = append(miner.txs, tx)
				}
			}
		default:
			// This hack is only temporarily
			if len(miner.txs) == 0 {
				time.Sleep(2 * time.Second)
				continue
			}

			miner.mineNewBlock()
		}
	}
}

func (miner *Miner) Stop() {
	logger.Infoln("Stopping...")

	miner.powQuitChan <- ethreact.Event{}

	status := make(chan error)
	miner.quitChan <- status
	<-status

	reactor := miner.ethereum.Reactor()
	reactor.Unsubscribe("newBlock", miner.powQuitChan)
	reactor.Unsubscribe("newTx:pre", miner.powQuitChan)
	reactor.Unsubscribe("newBlock", miner.reactChan)
	reactor.Unsubscribe("newTx:pre", miner.reactChan)

	reactor.Post("miner:stop", miner)
}

func (self *Miner) mineNewBlock() {

	stateManager := self.ethereum.StateManager()

	self.block = self.ethereum.BlockChain().NewBlock(self.coinbase)

	// Apply uncles
	if len(self.uncles) > 0 {
		self.block.SetUncles(self.uncles)
	}

	// Sort the transactions by nonce in case of odd network propagation
	sort.Sort(ethchain.TxByNonce{self.txs})

	// Accumulate all valid transactions and apply them to the new state
	// Error may be ignored. It's not important during mining
	parent := self.ethereum.BlockChain().GetBlock(self.block.PrevHash)
	coinbase := self.block.State().GetOrNewStateObject(self.block.Coinbase)
	coinbase.SetGasPool(self.block.CalcGasLimit(parent))
	receipts, txs, unhandledTxs, err := stateManager.ProcessTransactions(coinbase, self.block.State(), self.block, self.block, self.txs)
	if err != nil {
		logger.Debugln(err)
	}
	self.txs = append(txs, unhandledTxs...)
	self.block.SetTxHash(receipts)

	// Set the transactions to the block so the new SHA3 can be calculated
	self.block.SetReceipts(receipts, txs)

	// Accumulate the rewards included for this block
	stateManager.AccumelateRewards(self.block.State(), self.block, parent)

	self.block.State().Update()

	logger.Infof("Mining on block. Includes %v transactions", len(self.txs))

	// Find a valid nonce
	self.block.Nonce = self.pow.Search(self.block, self.powQuitChan)
	if self.block.Nonce != nil {
		err := self.ethereum.StateManager().Process(self.block, false)
		if err != nil {
			logger.Infoln(err)
		} else {
			self.ethereum.Broadcast(ethwire.MsgBlockTy, []interface{}{self.block.Value().Val})
			logger.Infof("🔨  Mined block %x\n", self.block.Hash())
			logger.Infoln(self.block)
			// Gather the new batch of transactions currently in the tx pool
			self.txs = self.ethereum.TxPool().CurrentTransactions()
		}
	}
}
<|endoftext|>


<commit_before>package ethutil

import (
	"fmt"
	"math/big"
	"os"
	"os/user"
	"path"
	"path/filepath"
	"runtime"
	"time"

	"github.com/kardianos/osext"
)

func DefaultAssetPath() string {
	var assetPath string
	pwd, _ := os.Getwd()
	srcdir := path.Join(os.Getenv("GOPATH"), "src", "github.com", "ethereum", "go-ethereum", "cmd", "mist")

	// If the current working directory is the go-ethereum dir
	// assume a debug build and use the source directory as
	// asset directory.
	if pwd == srcdir {
		assetPath = path.Join(pwd, "assets")
	} else {
		switch runtime.GOOS {
		case "darwin":
			// Get Binary Directory
			exedir, _ := osext.ExecutableFolder()
			assetPath = filepath.Join(exedir, "../Resources")
		case "linux":
			assetPath = "/usr/share/mist"
		case "windows":
			assetPath = "./assets"
		default:
			assetPath = "."
		}

		// Check if the assetPath exists. If not, try the source directory
		// This happens when binary is run from outside cmd/mist directory
		if _, err := os.Stat(assetPath); os.IsNotExist(err) {
			assetPath = path.Join(srcdir, "assets")
		}
	}
	return assetPath
}

func DefaultDataDir() string {
	usr, _ := user.Current()
	if runtime.GOOS == "darwin" {
		return path.Join(usr.HomeDir, "Library/Ethereum")
	} else if runtime.GOOS == "windows" {
		return path.Join(usr.HomeDir, "AppData/Roaming/Ethereum")
	} else {
		return path.Join(usr.HomeDir, ".ethereum")
	}
}
func IsWindows() bool {
	return runtime.GOOS == "windows"
}

func WindonizePath(path string) string {
	if string(path[0]) == "/" && IsWindows() {
		path = path[1:]
	}
	return path
}

// The different number of units
var (
	Douglas  = BigPow(10, 42)
	Einstein = BigPow(10, 21)
	Ether    = BigPow(10, 18)
	Finney   = BigPow(10, 15)
	Szabo    = BigPow(10, 12)
	Shannon  = BigPow(10, 9)
	Babbage  = BigPow(10, 6)
	Ada      = BigPow(10, 3)
	Wei      = big.NewInt(1)
)

//
// Currency to string
// Returns a string representing a human readable format
func CurrencyToString(num *big.Int) string {
	var (
		fin   *big.Int = num
		denom string   = "Wei"
	)

	switch {
	case num.Cmp(Douglas) >= 0:
		fin = new(big.Int).Div(num, Douglas)
		denom = "Douglas"
	case num.Cmp(Einstein) >= 0:
		fin = new(big.Int).Div(num, Einstein)
		denom = "Einstein"
	case num.Cmp(Ether) >= 0:
		fin = new(big.Int).Div(num, Ether)
		denom = "Ether"
	case num.Cmp(Finney) >= 0:
		fin = new(big.Int).Div(num, Finney)
		denom = "Finney"
	case num.Cmp(Szabo) >= 0:
		fin = new(big.Int).Div(num, Szabo)
		denom = "Szabo"
	case num.Cmp(Shannon) >= 0:
		fin = new(big.Int).Div(num, Shannon)
		denom = "Shannon"
	case num.Cmp(Babbage) >= 0:
		fin = new(big.Int).Div(num, Babbage)
		denom = "Babbage"
	case num.Cmp(Ada) >= 0:
		fin = new(big.Int).Div(num, Ada)
		denom = "Ada"
	}

	// TODO add comment clarifying expected behavior
	if len(fin.String()) > 5 {
		return fmt.Sprintf("%sE%d %s", fin.String()[0:5], len(fin.String())-5, denom)
	}

	return fmt.Sprintf("%v %s", fin, denom)
}

// Common big integers often used
var (
	Big1     = big.NewInt(1)
	Big2     = big.NewInt(2)
	Big3     = big.NewInt(3)
	Big0     = big.NewInt(0)
	BigTrue  = Big1
	BigFalse = Big0
	Big32    = big.NewInt(32)
	Big256   = big.NewInt(0xff)
	Big257   = big.NewInt(257)
)

func Bench(pre string, cb func()) {
	start := time.Now()
	cb()
	fmt.Println(pre, ": took:", time.Since(start))
}
<commit_msg>bump last resort check out of ifelse<commit_after>package ethutil

import (
	"fmt"
	"math/big"
	"os"
	"os/user"
	"path"
	"path/filepath"
	"runtime"
	"time"

	"github.com/kardianos/osext"
)

func DefaultAssetPath() string {
	var assetPath string
	pwd, _ := os.Getwd()
	srcdir := path.Join(os.Getenv("GOPATH"), "src", "github.com", "ethereum", "go-ethereum", "cmd", "mist")

	// If the current working directory is the go-ethereum dir
	// assume a debug build and use the source directory as
	// asset directory.
	if pwd == srcdir {
		assetPath = path.Join(pwd, "assets")
	} else {
		switch runtime.GOOS {
		case "darwin":
			// Get Binary Directory
			exedir, _ := osext.ExecutableFolder()
			assetPath = filepath.Join(exedir, "../Resources")
		case "linux":
			assetPath = "/usr/share/mist"
		case "windows":
			assetPath = "./assets"
		default:
			assetPath = "."
		}
	}

	// Check if the assetPath exists. If not, try the source directory
	// This happens when binary is run from outside cmd/mist directory
	if _, err := os.Stat(assetPath); os.IsNotExist(err) {
		assetPath = path.Join(srcdir, "assets")
	}

	return assetPath
}

func DefaultDataDir() string {
	usr, _ := user.Current()
	if runtime.GOOS == "darwin" {
		return path.Join(usr.HomeDir, "Library/Ethereum")
	} else if runtime.GOOS == "windows" {
		return path.Join(usr.HomeDir, "AppData/Roaming/Ethereum")
	} else {
		return path.Join(usr.HomeDir, ".ethereum")
	}
}
func IsWindows() bool {
	return runtime.GOOS == "windows"
}

func WindonizePath(path string) string {
	if string(path[0]) == "/" && IsWindows() {
		path = path[1:]
	}
	return path
}

// The different number of units
var (
	Douglas  = BigPow(10, 42)
	Einstein = BigPow(10, 21)
	Ether    = BigPow(10, 18)
	Finney   = BigPow(10, 15)
	Szabo    = BigPow(10, 12)
	Shannon  = BigPow(10, 9)
	Babbage  = BigPow(10, 6)
	Ada      = BigPow(10, 3)
	Wei      = big.NewInt(1)
)

//
// Currency to string
// Returns a string representing a human readable format
func CurrencyToString(num *big.Int) string {
	var (
		fin   *big.Int = num
		denom string   = "Wei"
	)

	switch {
	case num.Cmp(Douglas) >= 0:
		fin = new(big.Int).Div(num, Douglas)
		denom = "Douglas"
	case num.Cmp(Einstein) >= 0:
		fin = new(big.Int).Div(num, Einstein)
		denom = "Einstein"
	case num.Cmp(Ether) >= 0:
		fin = new(big.Int).Div(num, Ether)
		denom = "Ether"
	case num.Cmp(Finney) >= 0:
		fin = new(big.Int).Div(num, Finney)
		denom = "Finney"
	case num.Cmp(Szabo) >= 0:
		fin = new(big.Int).Div(num, Szabo)
		denom = "Szabo"
	case num.Cmp(Shannon) >= 0:
		fin = new(big.Int).Div(num, Shannon)
		denom = "Shannon"
	case num.Cmp(Babbage) >= 0:
		fin = new(big.Int).Div(num, Babbage)
		denom = "Babbage"
	case num.Cmp(Ada) >= 0:
		fin = new(big.Int).Div(num, Ada)
		denom = "Ada"
	}

	// TODO add comment clarifying expected behavior
	if len(fin.String()) > 5 {
		return fmt.Sprintf("%sE%d %s", fin.String()[0:5], len(fin.String())-5, denom)
	}

	return fmt.Sprintf("%v %s", fin, denom)
}

// Common big integers often used
var (
	Big1     = big.NewInt(1)
	Big2     = big.NewInt(2)
	Big3     = big.NewInt(3)
	Big0     = big.NewInt(0)
	BigTrue  = Big1
	BigFalse = Big0
	Big32    = big.NewInt(32)
	Big256   = big.NewInt(0xff)
	Big257   = big.NewInt(257)
)

func Bench(pre string, cb func()) {
	start := time.Now()
	cb()
	fmt.Println(pre, ": took:", time.Since(start))
}
<|endoftext|>


<commit_before>// Based on aplay audio adaptor written by @colemanserious (https://github.com/colemanserious)
package audio

import (
	"errors"
	"log"
	"os"
	"os/exec"
	"path"

	"github.com/hybridgroup/gobot"
)

var _ gobot.Adaptor = (*AudioAdaptor)(nil)

type AudioAdaptor struct {
	name string
}

func NewAudioAdaptor(name string) *AudioAdaptor {
	return &AudioAdaptor{
		name: name,
	}
}

func (a *AudioAdaptor) Name() string { return a.name }

func (a *AudioAdaptor) Connect() []error { return nil }

func (a *AudioAdaptor) Finalize() []error { return nil }

func (a *AudioAdaptor) Sound(fileName string) []error {

	var errorsList []error

	if fileName == "" {
		log.Println("Require filename for audio file.")
		errorsList = append(errorsList, errors.New("Requires filename for audio file."))
		return errorsList
	}

	_, err := os.Stat(fileName)
	if err != nil {
		log.Println(err)
		errorsList = append(errorsList, err)
		return errorsList
	}

	// command to play audio file based on file type
	fileType := path.Ext(fileName)
	var commandName string
	if fileType == ".mp3" {
			commandName = "mpg123"
	} else if fileType == ".wav" {
			commandName = "aplay"
	} else {
		log.Println("Unknown filetype for audio file.")
		errorsList = append(errorsList, errors.New("Unknown filetype for audio file."))
		return errorsList
	}

	cmd := exec.Command(commandName, fileName)
	err = cmd.Start()
	if err != nil {
		log.Println(err)
		errorsList = append(errorsList, err)
		return errorsList
	}

	// Need to return to fulfill function sig, even though returning an empty
	return nil
}
<commit_msg>[audio] Correct format of adaptor<commit_after>// Based on aplay audio adaptor written by @colemanserious (https://github.com/colemanserious)
package audio

import (
	"errors"
	"log"
	"os"
	"os/exec"
	"path"

	"github.com/hybridgroup/gobot"
)

var _ gobot.Adaptor = (*AudioAdaptor)(nil)

type AudioAdaptor struct {
	name string
}

func NewAudioAdaptor(name string) *AudioAdaptor {
	return &AudioAdaptor{
		name: name,
	}
}

func (a *AudioAdaptor) Name() string { return a.name }

func (a *AudioAdaptor) Connect() []error { return nil }

func (a *AudioAdaptor) Finalize() []error { return nil }

func (a *AudioAdaptor) Sound(fileName string) []error {

	var errorsList []error

	if fileName == "" {
		log.Println("Require filename for audio file.")
		errorsList = append(errorsList, errors.New("Requires filename for audio file."))
		return errorsList
	}

	_, err := os.Stat(fileName)
	if err != nil {
		log.Println(err)
		errorsList = append(errorsList, err)
		return errorsList
	}

	// command to play audio file based on file type
	fileType := path.Ext(fileName)
	var commandName string
	if fileType == ".mp3" {
		commandName = "mpg123"
	} else if fileType == ".wav" {
		commandName = "aplay"
	} else {
		log.Println("Unknown filetype for audio file.")
		errorsList = append(errorsList, errors.New("Unknown filetype for audio file."))
		return errorsList
	}

	cmd := exec.Command(commandName, fileName)
	err = cmd.Start()
	if err != nil {
		log.Println(err)
		errorsList = append(errorsList, err)
		return errorsList
	}

	// Need to return to fulfill function sig, even though returning an empty
	return nil
}
<|endoftext|>


<commit_before>package main

func problem9() int {
	return 0
}
<commit_msg>Solution to Project Euler problem 9<commit_after>package main

func problem9() int {
	for a := 1; a <= 997; a++ {
		for b := a + 1; b <= 997; b++ {
			for c := b + 1; c <= 997; c++ {
				if a+b+c == 1000 && (a*a)+(b*b) == (c*c) {
					return a * b * c
				}
			}
		}
	}
	return 0
}
<|endoftext|>


<commit_before>package eval_test

import (
	"fmt"
	"github.com/sriram-srinivasan/gore/eval"
	"strings"
	"testing"
)

func TestSimple(t *testing.T) {
	code := `fmt.Println("gore test")`
	check(t, code, "gore test", "")
}
func TestSimpleErr(t *testing.T) {
	code := `mt.Println("gore test")`
	check(t, code, "", ":1: undefined: mt")
}
func TestMultiline(t *testing.T) {
	code := `
              import (
                  "regexp"                        // Testing explicit import
              )
              foo := 10
              bar := math.Log10(100)             // Testing implicit import
              type Point struct {
                    x, y int
              }
              pt := Point{y: 1000, x: 100}
              if (pt.x <= 100) {
                  p "Case 1", foo, bar, pt
              } else {
                                                  // Testing nested curlies
                  if (pt.y > 1000)  {
                       p "Case 2", foo, bar, pt
                  }
              }
              // Check type
              t Point{10,100}, 0.34343
              regexp.MustCompile("foobar")
        `
	check(t, code, "Case 1\n10\n2\n{x:100 y:1000}\nmain.Point\nfloat64", "")
}

func TestMultilineError(t *testing.T) {
	code := `
             foo := 10
             math.log(100) // Using log instead of Log to provoke error
        `
	check(t, code, "", ":3: cannot refer to unexported name math.log")
}

func TestImportRepair(t *testing.T) {
	// Using a var name ('math' here) that is identical to a standard package name. Eval should
	// import the "math" package and retry if the compiler complains about duplicate packages
	code := `
           type M struct{
               x int
           }
        math := M{100}
        p math.x
        `
	check(t, code, "100", "")
}

var ts = strings.TrimSpace

func check(t *testing.T, code string, expected_out string, expected_err string) {
	out, err := eval.Eval(code)
	if !(ts(expected_out) == ts(out)) {
		t.Error(fmt.Sprintf("Expected output to be \n%s\nInstead got:\n%s\n", out, expected_out))
	}
	if !(ts(expected_err) == ts(err)) {
		t.Error(fmt.Sprintf("Expected compiler error to be \n%s\n. Instead got:\n%s\n", err, expected_err))
	}
}
<commit_msg>Update eval_test.go<commit_after>package eval_test

import (
	"fmt"
	"github.com/sriram-srinivasan/gore/eval"
	"strings"
	"testing"
)

func TestSimple(t *testing.T) {
	code := `fmt.Println("gore test")`
	check(t, code, "gore test", "")
}
func TestSimpleErr(t *testing.T) {
	code := `mt.Println("gore test")`
	check(t, code, "", ":1: undefined: mt")
}
func TestMultiline(t *testing.T) {
	code := `
              import (
                  "regexp"                        // Testing explicit import
              )
              foo := 10
              bar := math.Log10(100)             // Testing implicit import
              type Point struct {
                    x, y int
              }
              pt := Point{y: 1000, x: 100}
              if (pt.x <= 100) {
                  p "Case 1", foo, bar, pt
              } else {
                                                  // Testing nested curlies
                  if (pt.y > 1000)  {
                       p "Case 2", foo, bar, pt
                  }
              }
              // Check type
              t Point{10,100}, 0.34343
              regexp.MustCompile("foobar")
        `
	check(t, code, "Case 1\n10\n2\n{x:100 y:1000}\nmain.Point\nfloat64", "")
}

func TestMultilineRawString(t *testing.T) {
	code := "fmt.Println(`gore raw string\nmultiline test`)"
	check(t, code, "gore raw string\nmultiline test", "")
}

func TestMultilineError(t *testing.T) {
	code := `
             foo := 10
             math.log(100) // Using log instead of Log to provoke error
        `
	check(t, code, "", ":3: cannot refer to unexported name math.log")
}

func TestImportRepair(t *testing.T) {
	// Using a var name ('math' here) that is identical to a standard package name. Eval should
	// import the "math" package and retry if the compiler complains about duplicate packages
	code := `
           type M struct{
               x int
           }
        math := M{100}
        p math.x
        `
	check(t, code, "100", "")
}

var ts = strings.TrimSpace

func check(t *testing.T, code string, expected_out string, expected_err string) {
	out, err := eval.Eval(code)
	if !(ts(expected_out) == ts(out)) {
		t.Error(fmt.Sprintf("Expected output to be:\n%s\n\nInstead got:\n%s\n", expected_out, out))
	}
	if !(ts(expected_err) == ts(err)) {
		t.Error(fmt.Sprintf("Expected compiler error to be:\n%s\n\nInstead got:\n%s\n", expected_err, err))
	}
}
<|endoftext|>


<commit_before>package eval

import (
	"bytes"
	"testing"
)

func TestExecCmd(t *testing.T) {
	var in, out, err bytes.Buffer
	e := New(&in, &out, &err)
	if err := e.execCmd("echo", []string{"aaa"}); err != nil {
		t.Errorf("execute command: %v", err)
	}
	if got, want := out.String(), "aaa\n"; got != want {
		t.Errorf("output: got %q, want %q", got, want)
	}
	if got := err.String(); got != "" {
		t.Errorf("error should be blank; got %q", got)
	}
}
<commit_msg>Add a test case for eval.Evaluator.execPipe<commit_after>package eval

import (
	"bytes"
	"testing"
)

func TestExecCmd(t *testing.T) {
	var in, out, err bytes.Buffer
	e := New(&in, &out, &err)
	if err := e.execCmd("echo", []string{"aaa"}); err != nil {
		t.Errorf("execute command: %v", err)
	}
	if got, want := out.String(), "aaa\n"; got != want {
		t.Errorf("output: got %q, want %q", got, want)
	}
	if got := err.String(); got != "" {
		t.Errorf("error should be blank; got %q", got)
	}
}

func TestExecPipe(t *testing.T) {
	var in, out, err bytes.Buffer
	e := New(&in, &out, &err)
	if err := e.execPipe([][]string{
		[]string{
			"echo",
			"aaa",
		},
		[]string{
			"tr",
			"a",
			"A",
		},
	}); err != nil {
		t.Errorf("execute pipe: %v", err)
	}
	if got, want := out.String(), "AAA\n"; got != want {
		t.Errorf("output: got %q, want %q", got, want)
	}
	if got := err.String(); got != "" {
		t.Errorf("error should be blank; got %q", got)
	}
}
<|endoftext|>


<commit_before>package vals

import (
	"fmt"

	"github.com/xiaq/persistent/hashmap"
	"github.com/xiaq/persistent/vector"
)

// Kinder wraps the Kind method.
type Kinder interface {
	Kind() string
}

// Kind returns the "kind" of the value, a concept similar to type but not yet
// very well defined. It is implemented for the builtin types bool and string,
// the Vector and Map types, and types implementing the Kinder interface. For
// other types, it returns the Go type name of the argument preceeded by "!!".
func Kind(v interface{}) string {
	switch v := v.(type) {
	case Kinder:
		return v.Kind()
	case bool:
		return "bool"
	case string:
		return "string"
	case vector.Vector:
		return "list"
	case hashmap.Map:
		return "map"
	default:
		return fmt.Sprintf("!!%T", v)
	}
}
<commit_msg>eval/vals: Fix typo in comment<commit_after>package vals

import (
	"fmt"

	"github.com/xiaq/persistent/hashmap"
	"github.com/xiaq/persistent/vector"
)

// Kinder wraps the Kind method.
type Kinder interface {
	Kind() string
}

// Kind returns the "kind" of the value, a concept similar to type but not yet
// very well defined. It is implemented for the builtin types bool and string,
// the Vector and Map types, and types implementing the Kinder interface. For
// other types, it returns the Go type name of the argument preceded by "!!".
func Kind(v interface{}) string {
	switch v := v.(type) {
	case Kinder:
		return v.Kind()
	case bool:
		return "bool"
	case string:
		return "string"
	case vector.Vector:
		return "list"
	case hashmap.Map:
		return "map"
	default:
		return fmt.Sprintf("!!%T", v)
	}
}
<|endoftext|>


<commit_before>package event

import (
	"net/url"
	"time"

	"github.com/mitchellh/mapstructure"
)

// Connpass implements Api
// Connpass represents event data returned by Connpass.
type Connpass struct {
	result struct {
		Results_returned int
		Events           []struct {
			Event_id    string
			Title       string
			Catch       string
			Event_url   string
			Started_at  string
			Address     string
			Place       string
			Description string
		}
	}
}

func (self *Connpass) Get(baseurl, keyword, nickname string, places []string) ([]Event, error) {
	var events []Event
	for _, param := range []string{"keyword_or=" + url.QueryEscape(keyword), "owner_nickname=" + nickname, "nickname=" + nickname} {
		for t := time.Now().Local(); t.Before(time.Now().Local().AddDate(0, 3, 0)); t = t.AddDate(0, 1, 0) {
			query := param + "&ym=" + t.Format("200601")
			result, err := GetJson(baseurl + query)
			if err != nil {
				return nil, err
			}
			if err = mapstructure.WeakDecode(result, &self.result); err != nil {
				return nil, err
			}
			for _, e := range self.result.Events {
				event := Event{
					Id:          e.Event_id,
					Title:       e.Title,
					Started_at:  format(e.Started_at),
					Url:         e.Event_url,
					Summary:     e.Catch,
					Place:       e.Address + "\n" + e.Place,
					Description: e.Description,
				}
				if event.Summary == "" {
					event.Summary = trim(event.Description)
				}
				events = append(events, event)
			}
			time.Sleep(time.Duration(1 * time.Second))
		}
	}
	return events, nil
}
<commit_msg>parse the description from connpass<commit_after>package event

import (
	"net/url"
	"time"

	"github.com/mitchellh/mapstructure"
)

// Connpass implements Api
// Connpass represents event data returned by Connpass.
type Connpass struct {
	result struct {
		Results_returned int
		Events           []struct {
			Event_id    string
			Title       string
			Catch       string
			Event_url   string
			Started_at  string
			Address     string
			Place       string
			Description string
		}
	}
}

func (self *Connpass) Get(baseurl, keyword, nickname string, places []string) ([]Event, error) {
	var events []Event
	for _, param := range []string{"keyword_or=" + url.QueryEscape(keyword), "owner_nickname=" + nickname, "nickname=" + nickname} {
		for t := time.Now().Local(); t.Before(time.Now().Local().AddDate(0, 3, 0)); t = t.AddDate(0, 1, 0) {
			query := param + "&ym=" + t.Format("200601")
			result, err := GetJson(baseurl + query)
			if err != nil {
				return nil, err
			}
			if err = mapstructure.WeakDecode(result, &self.result); err != nil {
				return nil, err
			}
			for _, e := range self.result.Events {
				event := Event{
					Id:          e.Event_id,
					Title:       e.Title,
					Started_at:  format(e.Started_at),
					Url:         e.Event_url,
					Summary:     e.Catch,
					Place:       e.Address + "\n" + e.Place,
					Description: parse(e.Description),
				}
				if event.Summary == "" {
					event.Summary = trim(event.Description)
				}
				events = append(events, event)
			}
			time.Sleep(time.Duration(1 * time.Second))
		}
	}
	return events, nil
}
<|endoftext|>


<commit_before>package mock

import (
	"bytes"
	"context"
	"fmt"
	"net/http"
	"os"
	"sync"
	"time"

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

	"github.com/gogo/protobuf/jsonpb"
	"github.com/gogo/protobuf/proto"
	"github.com/golang/protobuf/ptypes/empty"
	"github.com/segmentio/ksuid"

	"zvelo.io/msg"
)

var jsonMarshaler jsonpb.Marshaler

type apiServer struct {
	requestsLock sync.Mutex
	requests     map[string]*result

	streamsLock sync.Mutex
	streams     map[chan *msg.QueryResult]struct{}
}

type result struct {
	msg.QueryResult
	StoredAt      time.Time
	CompleteAfter time.Duration
}

func (r result) CompleteAt() time.Time {
	return r.StoredAt.Add(r.CompleteAfter)
}

func (r result) Complete() bool {
	return time.Now().After(r.CompleteAt())
}

func (r result) Clone() (*result, error) {
	var cpy msg.QueryResult
	if err := copyProto(&cpy, &r.QueryResult); err != nil {
		return nil, err
	}
	r.QueryResult = cpy
	return &r, nil
}

var _ msg.APIv1Server = (*apiServer)(nil)

func (s *apiServer) result(reqID string) (*result, error) {
	s.requestsLock.Lock()
	defer s.requestsLock.Unlock()

	r, ok := s.requests[reqID]
	if !ok || r == nil {
		return nil, status.Errorf(codes.NotFound, "request ID not found: %s", reqID)
	}

	r, err := r.Clone()
	if err != nil {
		return nil, err
	}

	if r.Complete() {
		if r.QueryStatus == nil {
			r.QueryStatus = &msg.QueryStatus{}
		}

		r.QueryStatus.Complete = true
	}

	return r, nil
}

func copyProto(dst, src proto.Message) error {
	data, err := proto.Marshal(src)
	if err != nil {
		return err
	}

	return proto.Unmarshal(data, dst)
}

func (s *apiServer) store(r *result) {
	s.requestsLock.Lock()
	defer s.requestsLock.Unlock()

	r.StoredAt = time.Now()

	if s.requests == nil {
		s.requests = map[string]*result{}
	}

	s.requests[r.RequestId] = r
}

func (s *apiServer) handleResult(callbackURL, reqID string) {
	result, err := s.result(reqID)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		return
	}

	if result == nil {
		return
	}

	if !result.Complete() {
		time.AfterFunc(time.Until(result.CompleteAt()), func() {
			s.handleResult(callbackURL, reqID)
		})
		return
	}

	if callbackURL != "" {
		var buf bytes.Buffer
		if err = jsonMarshaler.Marshal(&buf, &result.QueryResult); err == nil {
			if _, err = http.Post(callbackURL, "application/json", &buf); err != nil {
				fmt.Fprintf(os.Stderr, "error posting callback: %s\n", err)
			}
		}
	}

	s.streamsLock.Lock()
	defer s.streamsLock.Unlock()

	for stream := range s.streams {
		select {
		case stream <- &result.QueryResult:
		default:
		}
	}
}

func (s *apiServer) handleResults(callbackURL string, reqIDs ...string) {
	for _, reqID := range reqIDs {
		go s.handleResult(callbackURL, reqID)
	}
}

func (s *apiServer) handleQuery(ctx context.Context, u string, content bool, ds []msg.DataSetType, out *msg.QueryReplies, reqIDs *[]string) error {
	var r result
	if err := parseOpts(ctx, u, content, ds, &r); err != nil {
		return status.Errorf(codes.Internal, "error parsing opts: %s", err)
	}

	r.RequestId = ksuid.New().String()
	*reqIDs = append(*reqIDs, r.RequestId)

	s.store(&r)

	out.Reply = append(out.Reply, &msg.QueryReply{
		RequestId: r.RequestId,
	})

	return nil
}

func (s *apiServer) Query(ctx context.Context, in *msg.QueryRequests) (*msg.QueryReplies, error) {
	if len(in.Dataset) == 0 {
		return nil, status.Error(codes.InvalidArgument, "no datasets requested")
	}

	var out msg.QueryReplies
	var reqIDs []string

	for _, u := range in.Url {
		if u == "" {
			continue
		}

		if err := s.handleQuery(ctx, u, false, in.Dataset, &out, &reqIDs); err != nil {
			return nil, err
		}
	}

	for _, c := range in.Content {
		if c == nil || (c.Url == "" && c.Content == "") {
			continue
		}

		if err := s.handleQuery(ctx, c.Url, true, in.Dataset, &out, &reqIDs); err != nil {
			return nil, err
		}
	}

	if len(reqIDs) == 0 {
		return nil, status.Error(codes.InvalidArgument, "no valid urls in request")
	}

	defer s.handleResults(in.Callback, reqIDs...)

	return &out, nil
}

func (s *apiServer) Result(_ context.Context, in *msg.RequestID) (*msg.QueryResult, error) {
	result, err := s.result(in.RequestId)
	if err != nil {
		return nil, err
	}

	return &result.QueryResult, nil
}

func (s *apiServer) Suggest(_ context.Context, _ *msg.Suggestion) (*empty.Empty, error) {
	return &empty.Empty{}, nil
}

func (s *apiServer) registerStream() chan *msg.QueryResult {
	ch := make(chan *msg.QueryResult)

	s.streamsLock.Lock()
	if s.streams == nil {
		s.streams = map[chan *msg.QueryResult]struct{}{}
	}
	s.streams[ch] = struct{}{}
	s.streamsLock.Unlock()

	return ch
}

func (s *apiServer) unregisterStream(ch chan *msg.QueryResult) {
	s.streamsLock.Lock()
	delete(s.streams, ch)
	s.streamsLock.Unlock()
}

func (s *apiServer) Stream(_ *empty.Empty, stream msg.APIv1_StreamServer) error {
	ch := s.registerStream()
	defer s.unregisterStream(ch)

	if err := stream.SendHeader(nil); err != nil {
		return err
	}

	for {
		select {
		case result := <-ch:
			if err := stream.Send(result); err != nil {
				return err
			}
		case <-stream.Context().Done():
			return stream.Context().Err()
		}
	}
}
<commit_msg>fix json format in mock<commit_after>package mock

import (
	"bytes"
	"context"
	"fmt"
	"net/http"
	"os"
	"sync"
	"time"

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

	"github.com/gogo/protobuf/jsonpb"
	"github.com/gogo/protobuf/proto"
	"github.com/golang/protobuf/ptypes/empty"
	"github.com/segmentio/ksuid"

	"zvelo.io/msg"
)

var jsonMarshaler = jsonpb.Marshaler{OrigName: true}

type apiServer struct {
	requestsLock sync.Mutex
	requests     map[string]*result

	streamsLock sync.Mutex
	streams     map[chan *msg.QueryResult]struct{}
}

type result struct {
	msg.QueryResult
	StoredAt      time.Time
	CompleteAfter time.Duration
}

func (r result) CompleteAt() time.Time {
	return r.StoredAt.Add(r.CompleteAfter)
}

func (r result) Complete() bool {
	return time.Now().After(r.CompleteAt())
}

func (r result) Clone() (*result, error) {
	var cpy msg.QueryResult
	if err := copyProto(&cpy, &r.QueryResult); err != nil {
		return nil, err
	}
	r.QueryResult = cpy
	return &r, nil
}

var _ msg.APIv1Server = (*apiServer)(nil)

func (s *apiServer) result(reqID string) (*result, error) {
	s.requestsLock.Lock()
	defer s.requestsLock.Unlock()

	r, ok := s.requests[reqID]
	if !ok || r == nil {
		return nil, status.Errorf(codes.NotFound, "request ID not found: %s", reqID)
	}

	r, err := r.Clone()
	if err != nil {
		return nil, err
	}

	if r.Complete() {
		if r.QueryStatus == nil {
			r.QueryStatus = &msg.QueryStatus{}
		}

		r.QueryStatus.Complete = true
	}

	return r, nil
}

func copyProto(dst, src proto.Message) error {
	data, err := proto.Marshal(src)
	if err != nil {
		return err
	}

	return proto.Unmarshal(data, dst)
}

func (s *apiServer) store(r *result) {
	s.requestsLock.Lock()
	defer s.requestsLock.Unlock()

	r.StoredAt = time.Now()

	if s.requests == nil {
		s.requests = map[string]*result{}
	}

	s.requests[r.RequestId] = r
}

func (s *apiServer) handleResult(callbackURL, reqID string) {
	result, err := s.result(reqID)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		return
	}

	if result == nil {
		return
	}

	if !result.Complete() {
		time.AfterFunc(time.Until(result.CompleteAt()), func() {
			s.handleResult(callbackURL, reqID)
		})
		return
	}

	if callbackURL != "" {
		var buf bytes.Buffer
		if err = jsonMarshaler.Marshal(&buf, &result.QueryResult); err == nil {
			if _, err = http.Post(callbackURL, "application/json", &buf); err != nil {
				fmt.Fprintf(os.Stderr, "error posting callback: %s\n", err)
			}
		}
	}

	s.streamsLock.Lock()
	defer s.streamsLock.Unlock()

	for stream := range s.streams {
		select {
		case stream <- &result.QueryResult:
		default:
		}
	}
}

func (s *apiServer) handleResults(callbackURL string, reqIDs ...string) {
	for _, reqID := range reqIDs {
		go s.handleResult(callbackURL, reqID)
	}
}

func (s *apiServer) handleQuery(ctx context.Context, u string, content bool, ds []msg.DataSetType, out *msg.QueryReplies, reqIDs *[]string) error {
	var r result
	if err := parseOpts(ctx, u, content, ds, &r); err != nil {
		return status.Errorf(codes.Internal, "error parsing opts: %s", err)
	}

	r.RequestId = ksuid.New().String()
	*reqIDs = append(*reqIDs, r.RequestId)

	s.store(&r)

	out.Reply = append(out.Reply, &msg.QueryReply{
		RequestId: r.RequestId,
	})

	return nil
}

func (s *apiServer) Query(ctx context.Context, in *msg.QueryRequests) (*msg.QueryReplies, error) {
	if len(in.Dataset) == 0 {
		return nil, status.Error(codes.InvalidArgument, "no datasets requested")
	}

	var out msg.QueryReplies
	var reqIDs []string

	for _, u := range in.Url {
		if u == "" {
			continue
		}

		if err := s.handleQuery(ctx, u, false, in.Dataset, &out, &reqIDs); err != nil {
			return nil, err
		}
	}

	for _, c := range in.Content {
		if c == nil || (c.Url == "" && c.Content == "") {
			continue
		}

		if err := s.handleQuery(ctx, c.Url, true, in.Dataset, &out, &reqIDs); err != nil {
			return nil, err
		}
	}

	if len(reqIDs) == 0 {
		return nil, status.Error(codes.InvalidArgument, "no valid urls in request")
	}

	defer s.handleResults(in.Callback, reqIDs...)

	return &out, nil
}

func (s *apiServer) Result(_ context.Context, in *msg.RequestID) (*msg.QueryResult, error) {
	result, err := s.result(in.RequestId)
	if err != nil {
		return nil, err
	}

	return &result.QueryResult, nil
}

func (s *apiServer) Suggest(_ context.Context, _ *msg.Suggestion) (*empty.Empty, error) {
	return &empty.Empty{}, nil
}

func (s *apiServer) registerStream() chan *msg.QueryResult {
	ch := make(chan *msg.QueryResult)

	s.streamsLock.Lock()
	if s.streams == nil {
		s.streams = map[chan *msg.QueryResult]struct{}{}
	}
	s.streams[ch] = struct{}{}
	s.streamsLock.Unlock()

	return ch
}

func (s *apiServer) unregisterStream(ch chan *msg.QueryResult) {
	s.streamsLock.Lock()
	delete(s.streams, ch)
	s.streamsLock.Unlock()
}

func (s *apiServer) Stream(_ *empty.Empty, stream msg.APIv1_StreamServer) error {
	ch := s.registerStream()
	defer s.unregisterStream(ch)

	if err := stream.SendHeader(nil); err != nil {
		return err
	}

	for {
		select {
		case result := <-ch:
			if err := stream.Send(result); err != nil {
				return err
			}
		case <-stream.Context().Done():
			return stream.Context().Err()
		}
	}
}
<|endoftext|>


<commit_before>package logging

import (
	"io"
	"sort"
	"strings"
	"sync"

	"github.com/sirupsen/logrus"
	"github.com/spf13/viper"
)

var (
	// RootName of the root logger, defaults to root
	RootName string

	logKeys map[string]struct{}
)

func init() {
	RootName = "root"

	logKeys = map[string]struct{}{
		"level":  struct{}{},
		"format": struct{}{},
		"writer": struct{}{},
		"hooks":  struct{}{},
	}
}

// LoggerRegistry represents a registry for known loggers
type Registry struct {
	config *viper.Viper
	store  map[string]Logger
	lock   *sync.Mutex
}

// NewRegistry creates a new logger registry
func NewRegistry(cfg *viper.Viper, context logrus.Fields) *Registry {
	if cfg == nil {
		cfg = viper.New()
	}

	c := cfg
	if c.IsSet("logging") {
		c = cfg.Sub("logging")
	}

	var keys []string
	for _, kn := range c.AllKeys() {
		ln := strings.SplitN(kn, ".", 2)
		if _, ok := logKeys[ln[0]]; !ok {
			keys = append(keys, ln[0])
		}
	}

	store := make(map[string]Logger, len(keys))
	reg := &Registry{
		store:  store,
		config: c,
		lock:   new(sync.Mutex),
	}

	for _, k := range keys {

		// no sharing of context, so copy
		fields := make(logrus.Fields, len(context)+1)
		for kk, vv := range context {
			fields[kk] = vv
		}

		v := c
		if c.IsSet(k) {
			v = c.Sub(k)
		}

		addLoggingDefaults(v)
		fields["module"] = k
		if v.IsSet("name") {
			fields["module"] = v.GetString("name")
		}

		l := newNamedLogger(k, fields, v, nil)
		l.reg = reg
		reg.store[k] = l

	}

	if len(keys) == 0 {
		fields := make(logrus.Fields, len(context)+1)
		for k, v := range context {
			fields[k] = v
		}

		fields["module"] = RootName
		l := newNamedLogger(RootName, fields, c, nil)
		l.reg = reg
		reg.store[RootName] = l
	}

	return reg
}

// Get a logger by name, returns nil when logger doesn't exist.
// GetOK is the safe method to use.
func (r *Registry) Get(name string) Logger {
	l, ok := r.GetOK(name)
	if !ok {
		return nil
	}
	return l
}

// GetOK a logger by name, boolean is true when a logger was found
func (r *Registry) GetOK(name string) (Logger, bool) {
	r.lock.Lock()
	res, ok := r.store[strings.ToLower(name)]
	r.lock.Unlock()
	return res, ok
}

// Register a logger in this registry, overrides existing keys
func (r *Registry) Register(path string, logger Logger) {
	r.lock.Lock()
	r.store[strings.ToLower(path)] = logger
	r.lock.Unlock()
}

// Root returns the root logger, the name is configurable through the RootName variable
func (r *Registry) Root() Logger {
	return r.Get(RootName)
}

// Writer returns the pipe writer for the root logger
func (r *Registry) Writer() *io.PipeWriter {
	return r.Root().(*defaultLogger).Logger.Writer()
}

// Reload all the loggers with the new config
func (r *Registry) Reload() {
	r.lock.Lock()
	defer r.lock.Unlock()

	// Get all keys, sorted by name and shortest to longest
	var keys []string
	for key := range r.store {
		keys = append(keys, key)
	}
	sort.Strings(keys)

	// find matching config
	// for each key find the longest possible path that has a config
	// if no more path found or parts are exhausted use last config and stop searching
	configs := make(map[string]*viper.Viper, len(keys))
	for _, key := range keys {
		configs[key] = findLongestMatchingPath(key, r.config)
	}

	// call reconfigure on logger
	for _, k := range keys {
		logger := r.store[k]
		if cfg, ok := configs[k]; ok {
			logger.Configure(cfg)
		}
	}
}

func findLongestMatchingPath(path string, cfg *viper.Viper) *viper.Viper {
	parts := strings.Split(path, ".")
	pl := len(parts)
	for i := range parts {
		mod := pl - i
		k := strings.Join(parts[:mod], ".")
		if cfg.IsSet(k) {
			return cfg.Sub(k)
		}
	}
	return nil
}
<commit_msg>Fix crash on configuration update<commit_after>package logging

import (
	"io"
	"sort"
	"strings"
	"sync"

	"github.com/sirupsen/logrus"
	"github.com/spf13/viper"
)

var (
	// RootName of the root logger, defaults to root
	RootName string

	logKeys map[string]struct{}
)

func init() {
	RootName = "root"

	logKeys = map[string]struct{}{
		"level":  struct{}{},
		"format": struct{}{},
		"writer": struct{}{},
		"hooks":  struct{}{},
	}
}

// LoggerRegistry represents a registry for known loggers
type Registry struct {
	config *viper.Viper
	store  map[string]Logger
	lock   *sync.Mutex
}

// NewRegistry creates a new logger registry
func NewRegistry(cfg *viper.Viper, context logrus.Fields) *Registry {
	if cfg == nil {
		cfg = viper.New()
	}

	c := cfg
	if c.IsSet("logging") {
		c = cfg.Sub("logging")
	}

	var keys []string
	for _, kn := range c.AllKeys() {
		ln := strings.SplitN(kn, ".", 2)
		if _, ok := logKeys[ln[0]]; !ok {
			keys = append(keys, ln[0])
		}
	}

	store := make(map[string]Logger, len(keys))
	reg := &Registry{
		store:  store,
		config: c,
		lock:   new(sync.Mutex),
	}

	for _, k := range keys {

		// no sharing of context, so copy
		fields := make(logrus.Fields, len(context)+1)
		for kk, vv := range context {
			fields[kk] = vv
		}

		v := c
		if c.IsSet(k) {
			v = c.Sub(k)
		}

		addLoggingDefaults(v)
		fields["module"] = k
		if v.IsSet("name") {
			fields["module"] = v.GetString("name")
		}

		l := newNamedLogger(k, fields, v, nil)
		l.reg = reg
		reg.store[k] = l

	}

	if len(keys) == 0 {
		fields := make(logrus.Fields, len(context)+1)
		for k, v := range context {
			fields[k] = v
		}

		fields["module"] = RootName
		l := newNamedLogger(RootName, fields, c, nil)
		l.reg = reg
		reg.store[RootName] = l
	}

	return reg
}

// Get a logger by name, returns nil when logger doesn't exist.
// GetOK is the safe method to use.
func (r *Registry) Get(name string) Logger {
	l, ok := r.GetOK(name)
	if !ok {
		return nil
	}
	return l
}

// GetOK a logger by name, boolean is true when a logger was found
func (r *Registry) GetOK(name string) (Logger, bool) {
	r.lock.Lock()
	res, ok := r.store[strings.ToLower(name)]
	r.lock.Unlock()
	return res, ok
}

// Register a logger in this registry, overrides existing keys
func (r *Registry) Register(path string, logger Logger) {
	r.lock.Lock()
	r.store[strings.ToLower(path)] = logger
	r.lock.Unlock()
}

// Root returns the root logger, the name is configurable through the RootName variable
func (r *Registry) Root() Logger {
	return r.Get(RootName)
}

// Writer returns the pipe writer for the root logger
func (r *Registry) Writer() *io.PipeWriter {
	return r.Root().(*defaultLogger).Logger.Writer()
}

// Reload all the loggers with the new config
func (r *Registry) Reload() {
	r.lock.Lock()
	defer r.lock.Unlock()

	// Get all keys, sorted by name and shortest to longest
	var keys []string
	for key := range r.store {
		keys = append(keys, key)
	}
	sort.Strings(keys)

	// find matching config
	// for each key find the longest possible path that has a config
	// if no more path found or parts are exhausted use last config and stop searching
	configs := make(map[string]*viper.Viper, len(keys))
	for _, key := range keys {
		cfg := findLongestMatchingPath(key, r.config)
		if cfg != nil {
			configs[key] = findLongestMatchingPath(key, r.config)
		}
	}

	// call reconfigure on logger
	for _, k := range keys {
		logger := r.store[k]
		if cfg, ok := configs[k]; ok {
			logger.Configure(cfg)
		}
	}
}

func findLongestMatchingPath(path string, cfg *viper.Viper) *viper.Viper {
	parts := strings.Split(path, ".")
	pl := len(parts)
	for i := range parts {
		mod := pl - i
		k := strings.Join(parts[:mod], ".")
		if cfg.IsSet(k) {
			return cfg.Sub(k)
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package hammer

import (
	"fmt"
	"github.com/Sirupsen/logrus"
	"github.com/spf13/viper"
	"gopkg.in/yaml.v2"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"runtime"
	"strings"
)

type Target struct {
	Src      string `yaml:"src"`
	Dest     string `yaml:"dest"`
	Template bool   `yaml:"template"`
	Config   bool   `yaml:"config"`
}

type Package struct {
	Name         string     `yaml:"name"`
	Version      string     `yaml:"version"`
	Iteration    string     `yaml:"iteration"`
	Epoch        string     `yaml:"epoch"`
	License      string     `yaml:"license"`
	Vendor       string     `yaml:"vendor"`
	URL          string     `yaml:"url"`
	Description  string     `yaml:"description"`
	Architecture string     `yaml:"architecture"`
	Depends      []string   `yaml:"depends"`
	Resources    []Resource `yaml:"resources"`
	Targets      []Target   `yaml:"targets"`
	Scripts      Scripts    `yaml:"scripts"`
	ExtraArgs    string     `yaml:"extra-args"`

	// various roots
	BuildRoot  string `yaml:"-"`
	OutputRoot string `yaml:"-"`
	ScriptRoot string `yaml:"-"`
	SpecRoot   string `yaml:"-"`
	TargetRoot string `yaml:"-"`

	// information about the machine doing the building
	CPUs int `yaml:"-"`

	logger          *logrus.Entry
	template        *Template
	scriptLocations map[string]string
	fpm             *FPM
}

func NewPackageFromYAML(content []byte) (*Package, error) {
	p := new(Package)
	err := yaml.Unmarshal(content, p)

	if err != nil {
		return p, err
	}

	// machine information
	p.CPUs = runtime.NumCPU()

	// private fields
	p.SetLogger(logrus.StandardLogger())
	p.SetTemplate(NewTemplate(p))

	return p, nil
}

// setters
func (p *Package) SetLogger(logger *logrus.Logger) {
	p.logger = logger.WithField("name", p.Name)
}

func (p *Package) SetTemplate(tmpl *Template) {
	p.template = tmpl
}

// process
func (p *Package) BuildAndPackage() error {
	defer p.Cleanup()
	type Stage struct {
		Name   string
		Action func() error
	}
	stages := []Stage{
		{"setup", p.Setup},
		{"build", p.Build},
		{"package", p.Package},
	}

	for _, stage := range stages {
		logger := p.logger.WithField("stage", stage.Name)
		logger.Debugf("starting %s stage", stage.Name)
		err := stage.Action()
		if err != nil {
			logger.WithField("error", err).Error("could not complete stage")
			return err
		}
		logger.Infof("finished %s stage", stage.Name)
	}

	return nil
}

func (p *Package) Setup() error {
	roots := map[string]*string{
		"build":  &p.BuildRoot,
		"script": &p.ScriptRoot,
		"target": &p.TargetRoot,
	}

	for name, root := range roots {
		dir, err := ioutil.TempDir("", fmt.Sprintf("hammer-%s-%s", p.Name, name))
		if err != nil {
			p.logger.WithFields(logrus.Fields{
				"error": err,
				"root":  name,
			}).Errorf("could not create temporary directory")
			return err
		}

		*root = dir
	}

	// get the sources and store them in the temporary directory
	for _, s := range p.Resources {
		body, err := s.Download(p)
		if err != nil {
			return err
		}
		ioutil.WriteFile(
			path.Join(p.BuildRoot, s.Name(p)),
			body,
			0777,
		)
	}

	locations, err := p.Scripts.RenderAndWriteAll(p)
	if err != nil {
		return err
	}
	p.scriptLocations = locations

	// create an FPM instance
	fpm, err := NewFPM(p)
	if err != nil {
		return err
	}
	p.fpm = fpm

	return nil
}

func (p *Package) Cleanup() error {
	roots := map[string]string{
		"build":  p.BuildRoot,
		"script": p.ScriptRoot,
		"target": p.TargetRoot,
	}

	for root, dest := range roots {
		err := os.RemoveAll(dest)
		if err != nil {
			p.logger.WithFields(logrus.Fields{
				"error": err,
				"root":  root,
			}).Error("could not remove root during cleanup")
			return err
		}
	}

	return nil
}

func (p *Package) Build() error {
	// perform the build
	buildScript, ok := p.scriptLocations["build"]
	if !ok {
		p.logger.Warn("build script not found. skipping build stage.")
		return nil
	}

	cmd := exec.Command(viper.GetString("shell"), buildScript)
	cmd.Dir = p.BuildRoot
	out, err := cmd.CombinedOutput()
	if err != nil {
		p.logger.WithFields(logrus.Fields{
			"error":  err,
			"output": out,
		}).Error("build script exited with a non-zero exit code")
		return err
	}

	p.logger.WithFields(logrus.Fields{
		"systemTime": cmd.ProcessState.SystemTime(),
		"userTime":   cmd.ProcessState.UserTime(),
		"success":    cmd.ProcessState.Success(),
	}).Debug("build command exited")

	return nil
}

func (p *Package) Package() error {
	for _, outType := range strings.Split(viper.GetString("type"), ",") {
		p.logger.WithField("type", outType).Info("packaging with FPM")
		out, err := p.fpm.PackageFor(outType)
		if err != nil {
			p.logger.WithFields(logrus.Fields{
				"error":   err,
				"out":     string(out),
				"outType": outType,
			}).Error("failed to package")
			return err
		}
	}

	return nil
}
<commit_msg>package: log string for error instead of bytes<commit_after>package hammer

import (
	"fmt"
	"github.com/Sirupsen/logrus"
	"github.com/spf13/viper"
	"gopkg.in/yaml.v2"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"runtime"
	"strings"
)

type Target struct {
	Src      string `yaml:"src"`
	Dest     string `yaml:"dest"`
	Template bool   `yaml:"template"`
	Config   bool   `yaml:"config"`
}

type Package struct {
	Name         string     `yaml:"name"`
	Version      string     `yaml:"version"`
	Iteration    string     `yaml:"iteration"`
	Epoch        string     `yaml:"epoch"`
	License      string     `yaml:"license"`
	Vendor       string     `yaml:"vendor"`
	URL          string     `yaml:"url"`
	Description  string     `yaml:"description"`
	Architecture string     `yaml:"architecture"`
	Depends      []string   `yaml:"depends"`
	Resources    []Resource `yaml:"resources"`
	Targets      []Target   `yaml:"targets"`
	Scripts      Scripts    `yaml:"scripts"`
	ExtraArgs    string     `yaml:"extra-args"`

	// various roots
	BuildRoot  string `yaml:"-"`
	OutputRoot string `yaml:"-"`
	ScriptRoot string `yaml:"-"`
	SpecRoot   string `yaml:"-"`
	TargetRoot string `yaml:"-"`

	// information about the machine doing the building
	CPUs int `yaml:"-"`

	logger          *logrus.Entry
	template        *Template
	scriptLocations map[string]string
	fpm             *FPM
}

func NewPackageFromYAML(content []byte) (*Package, error) {
	p := new(Package)
	err := yaml.Unmarshal(content, p)

	if err != nil {
		return p, err
	}

	// machine information
	p.CPUs = runtime.NumCPU()

	// private fields
	p.SetLogger(logrus.StandardLogger())
	p.SetTemplate(NewTemplate(p))

	return p, nil
}

// setters
func (p *Package) SetLogger(logger *logrus.Logger) {
	p.logger = logger.WithField("name", p.Name)
}

func (p *Package) SetTemplate(tmpl *Template) {
	p.template = tmpl
}

// process
func (p *Package) BuildAndPackage() error {
	defer p.Cleanup()
	type Stage struct {
		Name   string
		Action func() error
	}
	stages := []Stage{
		{"setup", p.Setup},
		{"build", p.Build},
		{"package", p.Package},
	}

	for _, stage := range stages {
		logger := p.logger.WithField("stage", stage.Name)
		logger.Debugf("starting %s stage", stage.Name)
		err := stage.Action()
		if err != nil {
			logger.WithField("error", err).Error("could not complete stage")
			return err
		}
		logger.Infof("finished %s stage", stage.Name)
	}

	return nil
}

func (p *Package) Setup() error {
	roots := map[string]*string{
		"build":  &p.BuildRoot,
		"script": &p.ScriptRoot,
		"target": &p.TargetRoot,
	}

	for name, root := range roots {
		dir, err := ioutil.TempDir("", fmt.Sprintf("hammer-%s-%s", p.Name, name))
		if err != nil {
			p.logger.WithFields(logrus.Fields{
				"error": err,
				"root":  name,
			}).Errorf("could not create temporary directory")
			return err
		}

		*root = dir
	}

	// get the sources and store them in the temporary directory
	for _, s := range p.Resources {
		body, err := s.Download(p)
		if err != nil {
			return err
		}
		ioutil.WriteFile(
			path.Join(p.BuildRoot, s.Name(p)),
			body,
			0777,
		)
	}

	locations, err := p.Scripts.RenderAndWriteAll(p)
	if err != nil {
		return err
	}
	p.scriptLocations = locations

	// create an FPM instance
	fpm, err := NewFPM(p)
	if err != nil {
		return err
	}
	p.fpm = fpm

	return nil
}

func (p *Package) Cleanup() error {
	roots := map[string]string{
		"build":  p.BuildRoot,
		"script": p.ScriptRoot,
		"target": p.TargetRoot,
	}

	for root, dest := range roots {
		err := os.RemoveAll(dest)
		if err != nil {
			p.logger.WithFields(logrus.Fields{
				"error": err,
				"root":  root,
			}).Error("could not remove root during cleanup")
			return err
		}
	}

	return nil
}

func (p *Package) Build() error {
	// perform the build
	buildScript, ok := p.scriptLocations["build"]
	if !ok {
		p.logger.Warn("build script not found. skipping build stage.")
		return nil
	}

	cmd := exec.Command(viper.GetString("shell"), buildScript)
	cmd.Dir = p.BuildRoot
	out, err := cmd.CombinedOutput()
	if err != nil {
		p.logger.WithFields(logrus.Fields{
			"error":  err,
			"output": string(out),
		}).Error("build script exited with a non-zero exit code")
		return err
	}

	p.logger.WithFields(logrus.Fields{
		"systemTime": cmd.ProcessState.SystemTime(),
		"userTime":   cmd.ProcessState.UserTime(),
		"success":    cmd.ProcessState.Success(),
	}).Debug("build command exited")

	return nil
}

func (p *Package) Package() error {
	for _, outType := range strings.Split(viper.GetString("type"), ",") {
		p.logger.WithField("type", outType).Info("packaging with FPM")
		out, err := p.fpm.PackageFor(outType)
		if err != nil {
			p.logger.WithFields(logrus.Fields{
				"error":   err,
				"out":     string(out),
				"outType": outType,
			}).Error("failed to package")
			return err
		}
	}

	return nil
}
<|endoftext|>


<commit_before>package algoliaconnector

import (
	"math/rand"
	"socialapi/models"
	"socialapi/workers/common/runner"
	"strconv"

	"github.com/algolia/algoliasearch-client-go/algoliasearch"
	"github.com/koding/bongo"
	"labix.org/v2/mgo/bson"

	"testing"
	"time"

	. "github.com/smartystreets/goconvey/convey"
)

const algoliaSlownessSeconds = 2 * time.Second

func TestTopicSaved(t *testing.T) {
	r := runner.New("AlogoliaConnector-Test")
	err := r.Init()
	if err != nil {
		panic(err)
	}

	defer r.Close()

	algolia := algoliasearch.NewClient(r.Conf.Algolia.AppId, r.Conf.Algolia.ApiSecretKey)
	// create message handler
	handler := New(r.Log, algolia, r.Conf.Algolia.IndexSuffix)

	Convey("given some fake topic channel", t, func() {
		mockTopic := models.NewChannel()
		mockTopic.TypeConstant = models.Channel_TYPE_TOPIC
		Convey("it should save the document to algolia", func() {
			err := handler.TopicSaved(mockTopic)
			So(err, ShouldBeNil)
		})
	})
	Convey("given some fake non-topic channel", t, func() {
		mockTopic := models.NewChannel()
		mockTopic.TypeConstant = models.Channel_TYPE_PRIVATE_MESSAGE
		Convey("it should save the document to algolia", func() {
			err := handler.TopicSaved(mockTopic)
			So(err, ShouldBeNil)
		})
	})

}

func TestAccountSaved(t *testing.T) {
	handler := getTestHandler()
	Convey("given some fake account", t, func() {
		mockAccount := &models.Account{
			OldId:   bson.NewObjectId().Hex(),
			Id:      100000000,
			Nick:    "fake-nickname",
			IsTroll: false,
		}
		Convey("it should save the document to algolia", func() {
			err := handler.AccountSaved(mockAccount)
			So(err, ShouldBeNil)
		})
	})
}

func TestMessageListSaved(t *testing.T) {
	handler := getTestHandler()
	Convey("messages can be saved", t, func() {
		mockMessage, _ := createAndSaveMessage()
		mockListing := getListings(mockMessage)[0]

		So(handler.MessageListSaved(&mockListing), ShouldBeNil)

		time.Sleep(algoliaSlownessSeconds)

		record, err := handler.get("messages", strconv.FormatInt(mockMessage.Id, 10))
		So(err, ShouldBeNil)
		So(record, ShouldNotBeNil)
	})
	Convey("messages can be cross-indexed", t, func() {
		mockMessage, owner := createAndSaveMessage()

		// init channel
		cm, err := createChannel(owner.Id)
		So(err, ShouldBeNil)
		So(cm, ShouldNotBeNil)
		// init channel message list
		cml := createChannelMessageList(cm.Id, mockMessage.Id)
		So(cml, ShouldNotBeNil)

		listings := getListings(mockMessage)
		So(len(listings), ShouldEqual, 2)

		So(handler.MessageListSaved(&listings[0]), ShouldBeNil)
		time.Sleep(algoliaSlownessSeconds)
		So(handler.MessageListSaved(&listings[1]), ShouldBeNil)
		time.Sleep(algoliaSlownessSeconds)

		record, err := handler.get("messages", strconv.FormatInt(mockMessage.Id, 10))
		So(err, ShouldBeNil)
		So(len((record["_tags"]).([]interface{})), ShouldEqual, 2)
	})
}

func TestMessageListDeleted(t *testing.T) {
	handler := getTestHandler()
	Convey("messages can be deleted", t, func() {
		mockMessage, _ := createAndSaveMessage()
		mockListing := getListings(mockMessage)[0]

		So(handler.MessageListSaved(&mockListing), ShouldBeNil)

		time.Sleep(algoliaSlownessSeconds)

		So(handler.MessageListDeleted(&mockListing), ShouldBeNil)

		time.Sleep(algoliaSlownessSeconds)

		record, err := handler.get("messages", strconv.FormatInt(mockMessage.Id, 10))
		So(err.Error(), ShouldEqual, ErrAlgoliaObjectIdNotFound.Error())
		So(record, ShouldBeNil)
	})
	Convey("cross-indexed messages will not be deleted", t, func() {})
}

func TestMessageUpdated(t *testing.T) {
	Convey("messages can be updated", t, func() {})
}

func getTestHandler() *Controller {
	r := runner.New("AlogoliaConnector-Test")
	err := r.Init()
	if err != nil {
		panic(err)
	}

	defer r.Close()

	algolia := algoliasearch.NewClient(r.Conf.Algolia.AppId, r.Conf.Algolia.ApiSecretKey)
	// create message handler
	return New(r.Log, algolia, ".test")

}

func createAccount() (*models.Account, error) {
	// create and account instance
	author := models.NewAccount()

	// create a fake mongo id
	oldId := bson.NewObjectId()
	// assign it to our test user
	author.OldId = oldId.Hex()

	// seed the random data generator
	rand.Seed(time.Now().UnixNano())

	author.Nick = "malitest" + strconv.Itoa(rand.Intn(10e9))

	if err := author.Create(); err != nil {
		return nil, err
	}

	return author, nil
}

func createChannel(accountId int64) (*models.Channel, error) {
	// create and account instance
	channel := models.NewChannel()
	channel.CreatorId = accountId

	if err := channel.Create(); err != nil {
		return nil, err
	}

	return channel, nil
}

func createChannelMessageList(channelId, messageId int64) *models.ChannelMessageList {
	cml := models.NewChannelMessageList()

	cml.ChannelId = channelId
	cml.MessageId = messageId

	So(cml.Create(), ShouldBeNil)

	return cml
}

func createAndSaveMessage() (*models.ChannelMessage, *models.Account) {
	cm := models.NewChannelMessage()

	// init account
	account, err := createAccount()
	So(err, ShouldBeNil)
	So(account, ShouldNotBeNil)
	So(account.Id, ShouldNotEqual, 0)
	// init channel
	channel, err := createChannel(account.Id)
	So(err, ShouldBeNil)
	So(channel, ShouldNotBeNil)
	// set account id
	cm.AccountId = account.Id
	// set channel id
	cm.InitialChannelId = channel.Id
	// set body
	cm.Body = "5five"
	So(cm.Create(), ShouldBeNil)
	// init listing
	cml := createChannelMessageList(channel.Id, cm.Id)
	So(cml, ShouldNotBeNil)

	return cm, account
}

func getListings(message *models.ChannelMessage) []models.ChannelMessageList {
	mockListing := models.NewChannelMessageList()
	var listings []models.ChannelMessageList
	err := mockListing.Some(&listings, &bongo.Query{
		Selector: map[string]interface{}{"message_id": message.Id}})
	So(err, ShouldBeNil)
	return listings
}
<commit_msg>channel search: test for ChannelMessageUpdated<commit_after>package algoliaconnector

import (
	"math/rand"
	"socialapi/models"
	"socialapi/workers/common/runner"
	"strconv"

	"github.com/algolia/algoliasearch-client-go/algoliasearch"
	"github.com/koding/bongo"
	"labix.org/v2/mgo/bson"

	"testing"
	"time"

	. "github.com/smartystreets/goconvey/convey"
)

const algoliaSlownessSeconds = 2 * time.Second

func TestTopicSaved(t *testing.T) {
	r := runner.New("AlogoliaConnector-Test")
	err := r.Init()
	if err != nil {
		panic(err)
	}

	defer r.Close()

	algolia := algoliasearch.NewClient(r.Conf.Algolia.AppId, r.Conf.Algolia.ApiSecretKey)
	// create message handler
	handler := New(r.Log, algolia, r.Conf.Algolia.IndexSuffix)

	Convey("given some fake topic channel", t, func() {
		mockTopic := models.NewChannel()
		mockTopic.TypeConstant = models.Channel_TYPE_TOPIC
		Convey("it should save the document to algolia", func() {
			err := handler.TopicSaved(mockTopic)
			So(err, ShouldBeNil)
		})
	})
	Convey("given some fake non-topic channel", t, func() {
		mockTopic := models.NewChannel()
		mockTopic.TypeConstant = models.Channel_TYPE_PRIVATE_MESSAGE
		Convey("it should save the document to algolia", func() {
			err := handler.TopicSaved(mockTopic)
			So(err, ShouldBeNil)
		})
	})

}

func TestAccountSaved(t *testing.T) {
	handler := getTestHandler()
	Convey("given some fake account", t, func() {
		mockAccount := &models.Account{
			OldId:   bson.NewObjectId().Hex(),
			Id:      100000000,
			Nick:    "fake-nickname",
			IsTroll: false,
		}
		Convey("it should save the document to algolia", func() {
			err := handler.AccountSaved(mockAccount)
			So(err, ShouldBeNil)
		})
	})
}

func TestMessageListSaved(t *testing.T) {
	handler := getTestHandler()
	Convey("messages can be saved", t, func() {
		mockMessage, _ := createAndSaveMessage()
		mockListing := getListings(mockMessage)[0]

		So(handler.MessageListSaved(&mockListing), ShouldBeNil)

		time.Sleep(algoliaSlownessSeconds)

		record, err := handler.get("messages", strconv.FormatInt(mockMessage.Id, 10))
		So(err, ShouldBeNil)
		So(record, ShouldNotBeNil)
	})
	Convey("messages can be cross-indexed", t, func() {
		mockMessage, owner := createAndSaveMessage()

		// init channel
		cm, err := createChannel(owner.Id)
		So(err, ShouldBeNil)
		So(cm, ShouldNotBeNil)
		// init channel message list
		cml := createChannelMessageList(cm.Id, mockMessage.Id)
		So(cml, ShouldNotBeNil)

		listings := getListings(mockMessage)
		So(len(listings), ShouldEqual, 2)

		So(handler.MessageListSaved(&listings[0]), ShouldBeNil)
		time.Sleep(algoliaSlownessSeconds)
		So(handler.MessageListSaved(&listings[1]), ShouldBeNil)
		time.Sleep(algoliaSlownessSeconds)

		record, err := handler.get("messages", strconv.FormatInt(mockMessage.Id, 10))
		So(err, ShouldBeNil)
		So(len((record["_tags"]).([]interface{})), ShouldEqual, 2)
	})
}

func TestMessageListDeleted(t *testing.T) {
	handler := getTestHandler()
	Convey("messages can be deleted", t, func() {
		mockMessage, _ := createAndSaveMessage()
		mockListing := getListings(mockMessage)[0]

		So(handler.MessageListSaved(&mockListing), ShouldBeNil)

		time.Sleep(algoliaSlownessSeconds)

		So(handler.MessageListDeleted(&mockListing), ShouldBeNil)

		time.Sleep(algoliaSlownessSeconds)

		record, err := handler.get("messages", strconv.FormatInt(mockMessage.Id, 10))
		So(err.Error(), ShouldEqual, ErrAlgoliaObjectIdNotFound.Error())
		So(record, ShouldBeNil)
	})
	Convey("cross-indexed messages will not be deleted", t, func() {})
}

func TestMessageUpdated(t *testing.T) {
	handler := getTestHandler()
	Convey("messages can be updated", t, func() {
		mockMessage, _ := createAndSaveMessage()
		mockListing := getListings(mockMessage)[0]

		So(handler.MessageListSaved(&mockListing), ShouldBeNil)

		time.Sleep(algoliaSlownessSeconds)

		mockMessage.Body = "updated body"

		So(mockMessage.Update(), ShouldBeNil)
		So(handler.MessageUpdated(mockMessage), ShouldBeNil)

		time.Sleep(algoliaSlownessSeconds)

		record, err := handler.get("messages", strconv.FormatInt(mockMessage.Id, 10))
		So(err, ShouldBeNil)
		So(record["body"].(string), ShouldEqual, "updated body")
	})
}

func getTestHandler() *Controller {
	r := runner.New("AlogoliaConnector-Test")
	err := r.Init()
	if err != nil {
		panic(err)
	}

	defer r.Close()

	algolia := algoliasearch.NewClient(r.Conf.Algolia.AppId, r.Conf.Algolia.ApiSecretKey)
	// create message handler
	return New(r.Log, algolia, ".test")

}

func createAccount() (*models.Account, error) {
	// create and account instance
	author := models.NewAccount()

	// create a fake mongo id
	oldId := bson.NewObjectId()
	// assign it to our test user
	author.OldId = oldId.Hex()

	// seed the random data generator
	rand.Seed(time.Now().UnixNano())

	author.Nick = "malitest" + strconv.Itoa(rand.Intn(10e9))

	if err := author.Create(); err != nil {
		return nil, err
	}

	return author, nil
}

func createChannel(accountId int64) (*models.Channel, error) {
	// create and account instance
	channel := models.NewChannel()
	channel.CreatorId = accountId

	if err := channel.Create(); err != nil {
		return nil, err
	}

	return channel, nil
}

func createChannelMessageList(channelId, messageId int64) *models.ChannelMessageList {
	cml := models.NewChannelMessageList()

	cml.ChannelId = channelId
	cml.MessageId = messageId

	So(cml.Create(), ShouldBeNil)

	return cml
}

func createAndSaveMessage() (*models.ChannelMessage, *models.Account) {
	cm := models.NewChannelMessage()

	// init account
	account, err := createAccount()
	So(err, ShouldBeNil)
	So(account, ShouldNotBeNil)
	So(account.Id, ShouldNotEqual, 0)
	// init channel
	channel, err := createChannel(account.Id)
	So(err, ShouldBeNil)
	So(channel, ShouldNotBeNil)
	// set account id
	cm.AccountId = account.Id
	// set channel id
	cm.InitialChannelId = channel.Id
	// set body
	cm.Body = "5five"
	So(cm.Create(), ShouldBeNil)
	// init listing
	cml := createChannelMessageList(channel.Id, cm.Id)
	So(cml, ShouldNotBeNil)

	return cm, account
}

func getListings(message *models.ChannelMessage) []models.ChannelMessageList {
	mockListing := models.NewChannelMessageList()
	var listings []models.ChannelMessageList
	err := mockListing.Some(&listings, &bongo.Query{
		Selector: map[string]interface{}{"message_id": message.Id}})
	So(err, ShouldBeNil)
	return listings
}
<|endoftext|>


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

// An AS212 blackhole DNS server. Similar to the one found in evldns.
// Also see https://www.as112.net/

package main

import (
	"github.com/miekg/dns"
	"log"
	"os"
	"os/signal"
	"runtime"
	"syscall"
)

const SOA string = "@ SOA prisoner.iana.org. hostmaster.root-servers.org. 2002040800 1800 900 0604800 604800"

var zones = map[string]dns.RR{
	"10.in-addr.arpa.":      NewRR("$ORIGIN 10.in-addr.arpa.\n" + SOA),
	"254.169.in-addr.arpa.": NewRR("$ORIGIN 254.169.in-addr.arpa.\n" + SOA),
	"168.192.in-addr.arpa.": NewRR("$ORIGIN 168.192.in-addr.arpa.\n" + SOA),
	"16.172.in-addr.arpa.":  NewRR("$ORIGIN 16.172.in-addr.arpa.\n" + SOA),
	"17.172.in-addr.arpa.":  NewRR("$ORIGIN 17.172.in-addr.arpa.\n" + SOA),
	"18.172.in-addr.arpa.":  NewRR("$ORIGIN 18.172.in-addr.arpa.\n" + SOA),
	"19.172.in-addr.arpa.":  NewRR("$ORIGIN 19.172.in-addr.arpa.\n" + SOA),
	"20.172.in-addr.arpa.":  NewRR("$ORIGIN 20.172.in-addr.arpa.\n" + SOA),
	"21.172.in-addr.arpa.":  NewRR("$ORIGIN 21.172.in-addr.arpa.\n" + SOA),
	"22.172.in-addr.arpa.":  NewRR("$ORIGIN 22.172.in-addr.arpa.\n" + SOA),
	"23.172.in-addr.arpa.":  NewRR("$ORIGIN 23.172.in-addr.arpa.\n" + SOA),
	"24.172.in-addr.arpa.":  NewRR("$ORIGIN 24.172.in-addr.arpa.\n" + SOA),
	"25.172.in-addr.arpa.":  NewRR("$ORIGIN 25.172.in-addr.arpa.\n" + SOA),
	"26.172.in-addr.arpa.":  NewRR("$ORIGIN 26.172.in-addr.arpa.\n" + SOA),
	"27.172.in-addr.arpa.":  NewRR("$ORIGIN 27.172.in-addr.arpa.\n" + SOA),
	"28.172.in-addr.arpa.":  NewRR("$ORIGIN 28.172.in-addr.arpa.\n" + SOA),
	"29.172.in-addr.arpa.":  NewRR("$ORIGIN 29.172.in-addr.arpa.\n" + SOA),
	"30.172.in-addr.arpa.":  NewRR("$ORIGIN 30.172.in-addr.arpa.\n" + SOA),
	"31.172.in-addr.arpa.":  NewRR("$ORIGIN 31.172.in-addr.arpa.\n" + SOA),
}

func NewRR(s string) dns.RR {
	r, _ := dns.NewRR(s)
	return r
}

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU() * 4)
	for z, rr := range zones {
		rrx := rr.(*dns.SOA) // Some foo needed to created actual RR, on the not a reference
		dns.HandleFunc(z, func(w dns.ResponseWriter, r *dns.Msg) {
			m := new(dns.Msg)
			m.SetReply(r)
			m.Authoritative = true
			m.Ns = []dns.RR{rrx}
			w.WriteMsg(m)
		})
	}
	go func() {
		err := dns.ListenAndServe(":8053", "tcp", nil)
		if err != nil {
			log.Fatal("Failed to set tcp listener %s\n", err.Error())
		}
	}()
	go func() {
		err := dns.ListenAndServe(":8053", "udp", nil)
		if err != nil {
			log.Fatal("Failed to set tcp listener %s\n", err.Error())
		}
	}()
	sig := make(chan os.Signal)
	signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
	for {
		select {
		case s := <-sig:
			log.Fatalf("Signal (%d) received, stopping\n", s)
		}
	}
}
<commit_msg>Tweak<commit_after>// Copyright 2011 Miek Gieben. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// An AS212 blackhole DNS server. Similar to the one found in evldns.
// Also see https://www.as112.net/

package main

import (
	"github.com/miekg/dns"
	"log"
	"os"
	"os/signal"
	"runtime"
	"syscall"
)

const SOA string = "@ SOA prisoner.iana.org. hostmaster.root-servers.org. 2002040800 1800 900 0604800 604800"

func NewRR(s string) dns.RR { r, _ := dns.NewRR(s); return r }

var zones = map[string]dns.RR{
	"10.in-addr.arpa.":      NewRR("$ORIGIN 10.in-addr.arpa.\n" + SOA),
	"254.169.in-addr.arpa.": NewRR("$ORIGIN 254.169.in-addr.arpa.\n" + SOA),
	"168.192.in-addr.arpa.": NewRR("$ORIGIN 168.192.in-addr.arpa.\n" + SOA),
	"16.172.in-addr.arpa.":  NewRR("$ORIGIN 16.172.in-addr.arpa.\n" + SOA),
	"17.172.in-addr.arpa.":  NewRR("$ORIGIN 17.172.in-addr.arpa.\n" + SOA),
	"18.172.in-addr.arpa.":  NewRR("$ORIGIN 18.172.in-addr.arpa.\n" + SOA),
	"19.172.in-addr.arpa.":  NewRR("$ORIGIN 19.172.in-addr.arpa.\n" + SOA),
	"20.172.in-addr.arpa.":  NewRR("$ORIGIN 20.172.in-addr.arpa.\n" + SOA),
	"21.172.in-addr.arpa.":  NewRR("$ORIGIN 21.172.in-addr.arpa.\n" + SOA),
	"22.172.in-addr.arpa.":  NewRR("$ORIGIN 22.172.in-addr.arpa.\n" + SOA),
	"23.172.in-addr.arpa.":  NewRR("$ORIGIN 23.172.in-addr.arpa.\n" + SOA),
	"24.172.in-addr.arpa.":  NewRR("$ORIGIN 24.172.in-addr.arpa.\n" + SOA),
	"25.172.in-addr.arpa.":  NewRR("$ORIGIN 25.172.in-addr.arpa.\n" + SOA),
	"26.172.in-addr.arpa.":  NewRR("$ORIGIN 26.172.in-addr.arpa.\n" + SOA),
	"27.172.in-addr.arpa.":  NewRR("$ORIGIN 27.172.in-addr.arpa.\n" + SOA),
	"28.172.in-addr.arpa.":  NewRR("$ORIGIN 28.172.in-addr.arpa.\n" + SOA),
	"29.172.in-addr.arpa.":  NewRR("$ORIGIN 29.172.in-addr.arpa.\n" + SOA),
	"30.172.in-addr.arpa.":  NewRR("$ORIGIN 30.172.in-addr.arpa.\n" + SOA),
	"31.172.in-addr.arpa.":  NewRR("$ORIGIN 31.172.in-addr.arpa.\n" + SOA),
}

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU() * 4)
	for z, rr := range zones {
		rrx := rr.(*dns.SOA) // Some foo needed to created actual RR, on the not a reference
		dns.HandleFunc(z, func(w dns.ResponseWriter, r *dns.Msg) {
			m := new(dns.Msg)
			m.SetReply(r)
			m.Authoritative = true
			m.Ns = []dns.RR{rrx}
			w.WriteMsg(m)
		})
	}
	go func() {
		err := dns.ListenAndServe(":8053", "tcp", nil)
		if err != nil {
			log.Fatal("Failed to set tcp listener %s\n", err.Error())
		}
	}()
	go func() {
		err := dns.ListenAndServe(":8053", "udp", nil)
		if err != nil {
			log.Fatal("Failed to set tcp listener %s\n", err.Error())
		}
	}()
	sig := make(chan os.Signal)
	signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
	for {
		select {
		case s := <-sig:
			log.Fatalf("Signal (%d) received, stopping\n", s)
		}
	}
}
<|endoftext|>


<commit_before>package handlers

import (
	"crypto/tls"
	"net/http"
	"net/http/httputil"
	"net/url"
	"strconv"

	"github.com/tomsteele/shellsquid/app"
	"github.com/tomsteele/shellsquid/models"
)

func Proxy(server *app.App, isHttps bool) func(w http.ResponseWriter, req *http.Request) {
	return func(w http.ResponseWriter, req *http.Request) {
		record, err := models.FindRecordByFQDN(server.DB, req.Host)
		if err != nil || record.ID == "" {
			server.Render.Data(w, http.StatusNotFound, nil)
			return
		}
		if record.Blacklist {
			server.Render.Data(w, http.StatusNotFound, nil)
			return
		}
		u, err := url.Parse(record.HandlerProtocol + "://" + record.HandlerHost + ":" + strconv.Itoa(record.HandlerPort))
		if err != nil {
			server.Render.Data(w, http.StatusNotFound, nil)
			return
		}
		proxy := httputil.NewSingleHostReverseProxy(u)
		if isHttps {
			proxy.Transport = &http.Transport{
				TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
			}
		}
		proxy.ServeHTTP(w, req)
	}
}
<commit_msg>Parse hostname from host header<commit_after>package handlers

import (
	"crypto/tls"
	"net/http"
	"net/http/httputil"
	"net/url"
	"strconv"
	"strings"

	"github.com/tomsteele/shellsquid/app"
	"github.com/tomsteele/shellsquid/models"
)

func hostname(host string) string {
	parts := strings.SplitN(host, ":", 2)
	return parts[0]
}

func Proxy(server *app.App, isHttps bool) func(w http.ResponseWriter, req *http.Request) {
	return func(w http.ResponseWriter, req *http.Request) {
		record, err := models.FindRecordByFQDN(server.DB, hostname(req.Host))
		if err != nil || record.ID == "" {
			server.Render.Data(w, http.StatusNotFound, nil)
			return
		}
		if record.Blacklist {
			server.Render.Data(w, http.StatusNotFound, nil)
			return
		}
		u, err := url.Parse(record.HandlerProtocol + "://" + record.HandlerHost + ":" + strconv.Itoa(record.HandlerPort))
		if err != nil {
			server.Render.Data(w, http.StatusNotFound, nil)
			return
		}
		proxy := httputil.NewSingleHostReverseProxy(u)
		if isHttps {
			proxy.Transport = &http.Transport{
				TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
			}
		}
		proxy.ServeHTTP(w, req)
	}
}
<|endoftext|>


<commit_before>/** Author: Charney Kaye */

package main

// typedef unsigned char Uint16;
// void AudioCallback(void *userdata, Uint16 *stream, int len);
import "C"
import (
	log "github.com/Sirupsen/logrus"
	"time"

	"github.com/outrightmental/go-atomix"
	"github.com/veandco/go-sdl2/sdl"
)

const (
	sampleHz   = 44100
	numSamples = 4096
)

func main() {
	if err := sdl.Init(sdl.INIT_AUDIO); err != nil {
		log.WithFields(log.Fields{
			"error": err,
		}).Fatal("Cannot init SDL")
		return
	}
    defer func() {
        if r := recover(); r != nil {
			log.WithFields(log.Fields{
				"recover": r,
			}).Warn("Player Recovered")
        }
		sdl.PauseAudio(true)
		atomix.Teardown()
		sdl.Quit()
    }()

	var (
		step = 125 * time.Millisecond
		loops = 4
	)

	var (
		p808  = "assets/sounds/percussion/808/"
		kick1 = p808 + "kick1.wav"
		kick2 = p808 + "kick2.wav"
		snare = p808 + "snare.wav"
		marac = p808 + "maracas.wav"
	)

	atomix.Debug(true)
	atomix.Configure(sdl.AudioSpec{
			Freq:     sampleHz,
			Format:   sdl.AUDIO_S16,
			Channels: 1,
			Samples:  numSamples,
		})
	atomix.StartAt(time.Now().Add(1 * time.Second))

	t := 1 * time.Second // padding before music
	for n := 0; n < loops; n++ {
        atomix.SetFire(kick2, t,            0, 1.0, 0)
        atomix.SetFire(marac, t + 2 *step,  0, 0.5, 0)
        atomix.SetFire(snare, t + 4 *step,  0, 0.8, 0)
        atomix.SetFire(marac, t + 6 *step,  0, 0.5, 0)
        atomix.SetFire(kick1, t + 7 *step,  0, 0.9, 0)
        atomix.SetFire(marac, t + 8 *step,  0, 0.5, 0)
        atomix.SetFire(kick1, t + 10 *step, 0, 0.9, 0)
        atomix.SetFire(snare, t + 12 *step, 0, 0.8, 0)
        atomix.SetFire(marac, t + 14 *step, 0, 0.5, 0)
		t += 16 * step
	}

	spec := atomix.Spec()
	sdl.OpenAudio(spec, nil)
	sdl.PauseAudio(false)
	log.WithFields(log.Fields{
		"spec": spec,
	}).Info("SDL OpenAudio > Atomix")

	time.Sleep(t + 1 * time.Second) // padding after music
}
<commit_msg>that's a funky 808 jam if i say so<commit_after>/** Author: Charney Kaye */

package main

// typedef unsigned char Uint16;
// void AudioCallback(void *userdata, Uint16 *stream, int len);
import "C"
import (
	log "github.com/Sirupsen/logrus"
	"time"

	"github.com/outrightmental/go-atomix"
	"github.com/veandco/go-sdl2/sdl"
)

const (
	sampleHz   = 44100
	numSamples = 4096
)

func main() {
	if err := sdl.Init(sdl.INIT_AUDIO); err != nil {
		log.WithFields(log.Fields{
			"error": err,
		}).Fatal("Cannot init SDL")
		return
	}
    defer func() {
        if r := recover(); r != nil {
			log.WithFields(log.Fields{
				"recover": r,
			}).Warn("Player Recovered")
        }
		sdl.PauseAudio(true)
		atomix.Teardown()
		sdl.Quit()
    }()

	var (
		step = 125 * time.Millisecond
		loops = 4
	)

	var (
		p808  = "assets/sounds/percussion/808/"
		kick1 = p808 + "kick1.wav"
		kick2 = p808 + "kick2.wav"
		marac = p808 + "maracas.wav"
		snare = p808 + "snare.wav"
		hitom = p808 + "hightom.wav"
		clhat = p808 + "cl_hihat.wav"
	)

	atomix.Debug(true)
	atomix.Configure(sdl.AudioSpec{
			Freq:     sampleHz,
			Format:   sdl.AUDIO_S16,
			Channels: 1,
			Samples:  numSamples,
		})
	atomix.StartAt(time.Now().Add(1 * time.Second))

	t := 1 * time.Second // padding before music
	for n := 0; n < loops; n++ {
        atomix.SetFire(kick2, t,            0, 1.0, 0)
        atomix.SetFire(marac, t + 1 *step,  0, 0.5, 0)
        atomix.SetFire(clhat, t + 2 *step,  0, 0.5, 0)
        atomix.SetFire(marac, t + 3 *step,  0, 0.5, 0)
        atomix.SetFire(snare, t + 4 *step,  0, 0.8, 0)
        atomix.SetFire(marac, t + 5 *step,  0, 0.5, 0)
        atomix.SetFire(clhat, t + 6 *step,  0, 0.5, 0)
        atomix.SetFire(kick2, t + 7 *step,  0, 0.9, 0)
        atomix.SetFire(hitom, t + 8 *step,  0, 0.5, 0)
        atomix.SetFire(marac, t + 9 *step,  0, 0.5, 0)
        atomix.SetFire(hitom, t + 10 *step,  0, 0.5, 0)
        atomix.SetFire(marac, t + 11 *step,  0, 0.5, 0)
        atomix.SetFire(snare, t + 12 *step, 0, 0.8, 0)
        atomix.SetFire(kick1, t + 13 *step,  0, 0.9, 0)
        atomix.SetFire(hitom, t + 14 *step, 0, 0.5, 0)
        atomix.SetFire(marac, t + 15 *step,  0, 0.5, 0)
		t += 16 * step
	}

	spec := atomix.Spec()
	sdl.OpenAudio(spec, nil)
	sdl.PauseAudio(false)
	log.WithFields(log.Fields{
		"spec": spec,
	}).Info("SDL OpenAudio > Atomix")

	time.Sleep(t + 1 * time.Second) // padding after music
}
<|endoftext|>


<commit_before>package cluster

import (
	"sync"

	log "github.com/Sirupsen/logrus"
)

// Watchdog listens to cluster events and handles container rescheduling
type Watchdog struct {
	sync.Mutex
	cluster Cluster
}

// Handle handles cluster callbacks
func (w *Watchdog) Handle(e *Event) error {
	// Skip non-swarm events.
	if e.From != "swarm" {
		return nil
	}

	switch e.Status {
	case "engine_reconnect":
		go w.removeDuplicateContainers(e.Engine)
	case "engine_disconnect":
		go w.rescheduleContainers(e.Engine)
	}
	return nil
}

// removeDuplicateContainers removes duplicate containers when a node comes back
func (w *Watchdog) removeDuplicateContainers(e *Engine) {
	log.Debugf("removing duplicate containers from Node %s", e.ID)

	e.RefreshContainers(false)

	w.Lock()
	defer w.Unlock()

	for _, container := range e.Containers() {
		// skip non-swarm containers
		if container.Config.SwarmID() == "" {
			continue
		}

		for _, containerInCluster := range w.cluster.Containers() {
			if containerInCluster.Config.SwarmID() == container.Config.SwarmID() && containerInCluster.Engine.ID != container.Engine.ID {
				log.Debugf("container %s was rescheduled on node %s, removing it", container.ID, containerInCluster.Engine.Name)
				// container already exists in the cluster, destroy it
				if err := e.RemoveContainer(container, true, true); err != nil {
					log.Errorf("Failed to remove duplicate container %s on node %s: %v", container.ID, containerInCluster.Engine.Name, err)
				}
			}
		}
	}
}

// rescheduleContainers reschedules containers as soon as a node fails
func (w *Watchdog) rescheduleContainers(e *Engine) {
	w.Lock()
	defer w.Unlock()

	log.Debugf("Node %s failed - rescheduling containers", e.ID)
	for _, c := range e.Containers() {

		// Skip containers which don't have an "on-node-failure" reschedule policy.
		if !c.Config.HasReschedulePolicy("on-node-failure") {
			log.Debugf("Skipping rescheduling of %s based on rescheduling policies", c.ID)
			continue
		}

		// Remove the container from the dead engine. If we don't, then both
		// the old and new one will show up in docker ps.
		// We have to do this before calling `CreateContainer`, otherwise it
		// will abort because the name is already taken.
		c.Engine.removeContainer(c)

		newContainer, err := w.cluster.CreateContainer(c.Config, c.Info.Name, nil)

		if err != nil {
			log.Errorf("Failed to reschedule container %s: %v", c.ID, err)
			// add the container back, so we can retry later
			c.Engine.AddContainer(c)
		} else {
			log.Infof("Rescheduled container %s from %s to %s as %s", c.ID, c.Engine.Name, newContainer.Engine.Name, newContainer.ID)
			if c.Info.State.Running {
				log.Infof("Container %s was running, starting container %s", c.ID, newContainer.ID)
				if err := w.cluster.StartContainer(newContainer, nil); err != nil {
					log.Errorf("Failed to start rescheduled container %s: %v", newContainer.ID, err)
				}
			}
		}
	}

}

// NewWatchdog creates a new watchdog
func NewWatchdog(cluster Cluster) *Watchdog {
	log.Debugf("Watchdog enabled")
	w := &Watchdog{
		cluster: cluster,
	}
	cluster.RegisterEventHandler(w)
	return w
}
<commit_msg>fix issue #2162 add removeDuplicateContainers behaviour for every node when it's added.<commit_after>package cluster

import (
	"sync"

	log "github.com/Sirupsen/logrus"
)

// Watchdog listens to cluster events and handles container rescheduling
type Watchdog struct {
	sync.Mutex
	cluster Cluster
}

// Handle handles cluster callbacks
func (w *Watchdog) Handle(e *Event) error {
	// Skip non-swarm events.
	if e.From != "swarm" {
		return nil
	}

	switch e.Status {
	case "engine_connect", "engine_reconnect":
		go w.removeDuplicateContainers(e.Engine)
	case "engine_disconnect":
		go w.rescheduleContainers(e.Engine)
	}
	return nil
}

// removeDuplicateContainers removes duplicate containers when a node comes back
func (w *Watchdog) removeDuplicateContainers(e *Engine) {
	log.Debugf("removing duplicate containers from Node %s", e.ID)

	e.RefreshContainers(false)

	w.Lock()
	defer w.Unlock()

	for _, container := range e.Containers() {
		// skip non-swarm containers
		if container.Config.SwarmID() == "" {
			continue
		}

		for _, containerInCluster := range w.cluster.Containers() {
			if containerInCluster.Config.SwarmID() == container.Config.SwarmID() && containerInCluster.Engine.ID != container.Engine.ID {
				log.Debugf("container %s was rescheduled on node %s, removing it", container.ID, containerInCluster.Engine.Name)
				// container already exists in the cluster, destroy it
				if err := e.RemoveContainer(container, true, true); err != nil {
					log.Errorf("Failed to remove duplicate container %s on node %s: %v", container.ID, containerInCluster.Engine.Name, err)
				}
			}
		}
	}
}

// rescheduleContainers reschedules containers as soon as a node fails
func (w *Watchdog) rescheduleContainers(e *Engine) {
	w.Lock()
	defer w.Unlock()

	log.Debugf("Node %s failed - rescheduling containers", e.ID)
	for _, c := range e.Containers() {

		// Skip containers which don't have an "on-node-failure" reschedule policy.
		if !c.Config.HasReschedulePolicy("on-node-failure") {
			log.Debugf("Skipping rescheduling of %s based on rescheduling policies", c.ID)
			continue
		}

		// Remove the container from the dead engine. If we don't, then both
		// the old and new one will show up in docker ps.
		// We have to do this before calling `CreateContainer`, otherwise it
		// will abort because the name is already taken.
		c.Engine.removeContainer(c)

		newContainer, err := w.cluster.CreateContainer(c.Config, c.Info.Name, nil)

		if err != nil {
			log.Errorf("Failed to reschedule container %s: %v", c.ID, err)
			// add the container back, so we can retry later
			c.Engine.AddContainer(c)
		} else {
			log.Infof("Rescheduled container %s from %s to %s as %s", c.ID, c.Engine.Name, newContainer.Engine.Name, newContainer.ID)
			if c.Info.State.Running {
				log.Infof("Container %s was running, starting container %s", c.ID, newContainer.ID)
				if err := w.cluster.StartContainer(newContainer, nil); err != nil {
					log.Errorf("Failed to start rescheduled container %s: %v", newContainer.ID, err)
				}
			}
		}
	}

}

// NewWatchdog creates a new watchdog
func NewWatchdog(cluster Cluster) *Watchdog {
	log.Debugf("Watchdog enabled")
	w := &Watchdog{
		cluster: cluster,
	}
	cluster.RegisterEventHandler(w)
	return w
}
<|endoftext|>